Наше приложение отображает 2D-представление наших данных (в основном карты), а затем позволяет пользователю перейти к 3D-просмотру. 2D и 3D виды генерируются с помощью пользовательского кода C ++, который SWIG вставлен в наш графический интерфейс Swing и помещен в JComponent
. Эти JComponent
затем отображаются в другом родительском JComponent.
Наша проблема в том, что при изменении размера с 2D на 3D-вид и затем обратно на 2D-вид, когда мы изменяем размер окна, 2D-вид не изменяется. События изменения размера не отправляются в 2D-просмотр.
Наше приложение работает под Linux (Fedora 11). Мы используем Java версии 1.6.0_12.
Вот пример кода, в котором я заменил 2D-вид и 3D-вид двумя 2 JButton
s, что приводит к одинаковому поведению. После перехода в 3D, а затем обратно в 2D изменение размера окна не приводит к изменению размера 2D-вида.
/* TestFrame.java
* Compile with: $ javac TestFrame.java
* Run with: $ java TestFrame
*/
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import javax.swing.JButton;
public class TestFrame extends javax.swing.JFrame {
private boolean mode2D = true;
private JButton view2D = null;
private JButton view3D = null;
private Container parent = null;
public TestFrame() {
initComponents();
containerPanel.setLayout(new BorderLayout());
view2D = new JButton("2D View");
view2D.addComponentListener(new MyListener("2D VIEW"));
containerPanel.add(view2D);
}
private void changerButtonActionPerformed(java.awt.event.ActionEvent evt) {
if (parent == null) {
parent = view2D.getParent();
}
if (mode2D) {
System.out.println("Going from 2D to 3D");
view2D.setVisible(false);
if (view3D != null) {
view3D.setVisible(true);
} else {
view3D = new JButton("3D View");
view3D.addComponentListener(new MyListener("3D VIEW"));
parent.add(view3D);
}
((JButton) evt.getSource()).setText("Change to 2D");
mode2D = false;
} else {
System.out.println("Going from 3D to 2D");
view3D.setVisible(false);
view2D.setVisible(true);
((JButton) evt.getSource()).setText("Change to 3D");
mode2D = true;
}
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new TestFrame().setVisible(true);
}
});
}
private javax.swing.JPanel containerPanel;
private javax.swing.JButton changerButton;
private class MyListener implements ComponentListener {
private String name;
public MyListener(String name) {
this.name = name;
}
@Override
public void componentHidden(ComponentEvent event) {
System.out.println("@@@ [" + name + "] component Hidden");
}
@Override
public void componentResized(ComponentEvent event) {
System.out.println("@@@ [" + name + "] component Resized");
}
@Override
public void componentShown(ComponentEvent event) {
System.out.println("@@@ [" + name + "] component Shown");
}
@Override
public void componentMoved(ComponentEvent event) {
System.out.println("@@@ [" + name + "] component Moved");
}
};
@SuppressWarnings("unchecked")
private void initComponents() {
containerPanel = new javax.swing.JPanel();
changerButton = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
containerPanel.setBorder(new javax.swing.border.MatteBorder(null));
javax.swing.GroupLayout containerPanelLayout = new javax.swing.GroupLayout(containerPanel);
containerPanel.setLayout(containerPanelLayout);
containerPanelLayout.setHorizontalGroup(
containerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 374, Short.MAX_VALUE)
);
containerPanelLayout.setVerticalGroup(
containerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 239, Short.MAX_VALUE)
);
changerButton.setText("Change to 3D");
changerButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
changerButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(containerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(changerButton))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(containerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(changerButton)
.addContainerGap())
);
pack();
}
}
( Мои извинения за сгенерированный Netbeans код GUI )
Я должен упомянуть, что когда мы вызываем parent.remove(view2D)
и parent.add(view3D)
, чтобы изменить виды, X Windows ID нашего 3D-вида изменяется, и мы не можем вернуть наш 3D-вид назад. Поэтому parent.remove(view2D)
и parent.add(view3D)
на самом деле не являются решением, и мы должны вызвать setVisible(false)
и setVisible(true)
на JComponent
s, которые содержат наши 2D и 3D виды, чтобы скрыть и показать их.
Любая помощь будет принята с благодарностью.