Изменение размера проблемы с canvas в 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);
Так как это мой первый вопрос, мне не разрешено вставлять изображение в вопрос, поэтому я просто опубликую ссылку:
Красные стрелки указывают положение делителя.
Спасибо заранее за ваше время.
3 ответа
После прочтения комментария davidbuzatto я погуглил по поводу смешивания компонентов AWT и Swing, и был немного удивлен, обнаружив, что это такая плохая практика.
Я нашел самый точный ответ на мой вопрос здесь
Тяжелые компоненты имеют собственный Z-порядок. По этой причине Swing и AWT не могут быть объединены в одном контейнере. Если это так, компоненты AWT будут отображаться в ТОП компонентов Swing.
Например: когда компоненты AWT используются с JtabbedPane, они не исчезают при переключении вкладок.
Спасибо Давидбузатто за то, что он показал мне путь:-)
Вместо setPreferredSize()
Позвольте вашим компонентам рассчитать их собственный предпочтительный размер и pack()
вмещающий Window
разместить. Пример ниже добавляет экземпляр draw.GraphPanel
сверху и соответствующая панель управления снизу.
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://stackru.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();
}
});
}
}
Как я сказал в моих комментариях, вы не должны смешивать компоненты 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();
}
}