Изменение размера с холстом в jscrollpane в jsplitpane
Я создаю приложение, используя редактор графического интерфейса NetBeans, в котором я хочу иметь JSplitPane
, верхний компонент которого будет Canvas
в пределах JScrollPane
, а нижний компонент будет JTextArea
, или что-то в этом роде.
Когда я вытаскиваю делитель вниз и, таким образом увеличивая размер верхнего компонента, все, кажется, очень просто изменяет размер.
Проблема возникает, когда я пытаюсь продвинуть разделитель вверх:
Похоже, что разделитель находится ниже Canvas
(и, возможно, ниже JScrollPane
).
Я пробовал различные комбинации предпочтительных/минимальных/максимальных размеров JScrollPane
и Canvas
, но ничего не работает.
Это часть кода, сгенерированного Netbeans, который может иметь какое-то отношение к проблеме:
jSplitPane1 = new javax.swing.JSplitPane();
jScrollPane1 = new javax.swing.JScrollPane();
canvas1 = new java.awt.Canvas();
jTextField1 = new javax.swing.JTextField();
jSplitPane1.setDividerLocation(300);
jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
jScrollPane1.setViewportView(canvas1);
jSplitPane1.setTopComponent(jScrollPane1);
jTextField1.setText("jTextField1");
jSplitPane1.setRightComponent(jTextField1);
Поскольку это мой первый вопрос, мне не разрешено вставлять изображение в вопрос, поэтому я просто отправлю ссылку:
![]()
Красные стрелки указывают положение разделителя.
Заранее благодарим за ваше время.
Ответы
Ответ 1
Прочитав комментарий от davidbuzatto, я разобрался в смешении компонентов AWT и Swing, и мне было немного неожиданно узнать, что это такая плохая практика.
Я нашел наиболее точный ответ на мой вопрос здесь
Тяжелые компоненты имеют собственный Z-порядок. Именно по этой причине Swing и AWT нельзя комбинировать в одном контейнере. Если они есть, компоненты AWT будут нарисованы поверх компонентов Swing.
Например: Когда AWT-компоненты используются с JtabbedPane, они не исчезают при переключении вкладок.
Спасибо davidbuzatto за то, что показал мне способ: -)
Ответ 2
Вместо setPreferredSize()
пусть ваши компоненты вычислит свой собственный предпочтительный размер и pack()
прилагаемый Window
для размещения. В приведенном ниже примере добавляется экземпляр draw.GraphPanel
вверху и соответствующая панель управления снизу.
![image]()
import draw.GraphPanel;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
/**
* @see https://stackoverflow.com/q/11942961/230513
*/
public class SplitGraph extends JPanel {
public SplitGraph() {
super(new GridLayout());
JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
GraphPanel graphPanel = new GraphPanel();
split.setTopComponent(new JScrollPane(graphPanel));
split.setBottomComponent(graphPanel.getControlPanel());
this.add(split);
}
private void display() {
JFrame f = new JFrame("SplitGraph");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new SplitGraph().display();
}
});
}
}
Ответ 3
Как я уже сказал в своих комментариях, вы не должны смешивать компоненты AWT и Swing. Я думаю, что вы не используете компоненты правильно. Взгляните, это простой пример использования JSplitPane.
import java.awt.*; // it is necessary to use the Dimension and BorderLayout classes
import javax.swing.*;
public class Foo extends JFrame {
public Foo() {
setTitle( "Splits" );
setDefaultCloseOperation( EXIT_ON_CLOSE );
setSize( 400, 400 );
JSplitPane split = new JSplitPane( JSplitPane.VERTICAL_SPLIT );
split.setDividerLocation( 200 );
add( split );
JPanel panel1 = new JPanel();
panel1.setLayout( new BorderLayout() );
panel1.add( new JLabel( "top panel" ), BorderLayout.NORTH );
JPanel myDrawPanel = new JPanel();
myDrawPanel.setPreferredSize( new Dimension( 100, 100 ) );
myDrawPanel.add( new JLabel( "draw panel here!" ) );
panel1.add( new JScrollPane( myDrawPanel ), BorderLayout.CENTER );
split.setTopComponent( panel1 );
JPanel panel2 = new JPanel();
panel2.add( new JLabel( "bottom panel" ) );
split.setBottomComponent( panel2 );
setVisible( true );
}
public static void main( String[] args ) {
new Foo();
}
}