我一直在尝试驯服JDesktopPane
可调整大小的 GUI 和滚动窗格,但我在这样做时遇到了一些麻烦。似乎除非拖动模式为轮廓,否则桌面窗格将不会按预期调整大小(当内部框架被拖动到桌面窗格边缘之外时),因此不会产生滚动条。
我在这个来源中做了一些非常愚蠢的事情吗?我错过了更好的方法吗?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class MDIPreferredSize {
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
final JDesktopPane dt = new JDesktopPane() {
@Override
public Dimension getPreferredSize() {
Dimension prefSize = super.getPreferredSize();
System.out.println("prefSize: " + prefSize);
// inititialize the max to the first normalized bounds
Rectangle max = getAllFrames()[0].getNormalBounds();
for (JInternalFrame jif : this.getAllFrames()) {
max.add(jif.getNormalBounds());
}
System.out.println("maxBounds(): "
+ max);
int x1 = max.width + (max.x * 2) < prefSize.width
? prefSize.width
: max.width + (max.x * 2);
int y1 = max.height + (max.y * 2) < prefSize.height
? prefSize.height
: max.height + (max.y * 2);
System.out.println("x,y: "
+ x1
+ ","
+ y1);
return new Dimension(x1, y1);
}
};
dt.setAutoscrolls(true);
int xx = 5;
int yy = 5;
int vStep = 10;
int yStep = 22;
for (int ii = 0; ii < 3; ii++) {
JInternalFrame jif = new JInternalFrame(
"Internal Frame " + (ii + 1),
true,
true,
true);
dt.add(jif);
jif.setLocation(xx, yy);
xx += vStep;
yy += yStep;
jif.setSize(200, 75);
jif.setVisible(true);
}
ComponentListener componentListener = new ComponentListener() {
@Override
public void componentResized(ComponentEvent e) {
e.getComponent().validate();
}
@Override
public void componentMoved(ComponentEvent e) {
e.getComponent().validate();
}
@Override
public void componentShown(ComponentEvent e) {
e.getComponent().validate();
}
@Override
public void componentHidden(ComponentEvent e) {
// do nothing
}
};
// causes maximized internal frames to be resized..
dt.addComponentListener(componentListener);
final JCheckBox outLineDragMode = new JCheckBox("Outline Drag Mode");
ActionListener dragModeListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (outLineDragMode.isSelected()) {
dt.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
} else {
dt.setDragMode(JDesktopPane.LIVE_DRAG_MODE);
}
}
};
outLineDragMode.addActionListener(dragModeListener);
JPanel gui = new JPanel(new BorderLayout());
gui.add(outLineDragMode, BorderLayout.PAGE_START);
gui.setBorder(new EmptyBorder(2, 3, 2, 3));
gui.add(new JScrollPane(dt), BorderLayout.CENTER);
JFrame f = new JFrame("DTP Preferred");
f.add(gui);
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See http://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
f.setMinimumSize(f.getSize());
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
printProperty("os.name");
printProperty("java.version");
printProperty("java.vendor");
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
public static void printProperty(String name) {
System.out.println(name + ": \t" + System.getProperty(name));
}
}
编辑
在打印的信息中,另请参阅 3 个系统属性:
os.name: Windows 7
java.version: 1.7.0_21
java.vendor: Oracle Corporation
这些就是这里的价值观。
MouseMotionListener
固定代码
感谢 Jonathan Drapeau 对 a 的建议MouseListener
,这个固定示例实际上使用 aMouseMotionListener
来允许在拖动时主动调整桌面窗格的大小。除了使用MouseListener
导致问题的 a 之外,它可能会遇到一些怪癖(尚不清楚),如果是这样,请回到更简单的技术“在内部框架放置时调整桌面窗格大小”(MouseListener
仅限)。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
public class MDIPreferredSize {
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
final JDesktopPane dt = new JDesktopPane() {
@Override
public Dimension getPreferredSize() {
Dimension prefSize = super.getPreferredSize();
System.out.println("prefSize: " + prefSize);
// inititialize the max to the first normalized bounds
Rectangle max = getAllFrames()[0].getNormalBounds();
for (JInternalFrame jif : this.getAllFrames()) {
max.add(jif.getNormalBounds());
}
System.out.println("maxBounds(): "
+ max);
int x1 = max.width + (max.x * 2) < prefSize.width
? prefSize.width
: max.width + (max.x * 2);
int y1 = max.height + (max.y * 2) < prefSize.height
? prefSize.height
: max.height + (max.y * 2);
System.out.println("x,y: "
+ x1
+ ","
+ y1);
return new Dimension(x1, y1);
}
};
int xx = 5;
int yy = 5;
int vStep = 10;
int yStep = 22;
for (int ii = 0; ii < 3; ii++) {
JInternalFrame jif = new JInternalFrame(
"Internal Frame " + (ii + 1),
true,
true,
true);
dt.add(jif);
jif.setLocation(xx, yy);
xx += vStep;
yy += yStep;
jif.setSize(200, 75);
jif.setVisible(true);
}
/*final MouseListener mouseListener = new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
dt.revalidate();
}
};
*/
final MouseMotionListener mouseMotionListener = new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
dt.revalidate();
}
};
for (JInternalFrame jif : dt.getAllFrames()) {
for (Component comp : jif.getComponents()) {
if (comp instanceof BasicInternalFrameTitlePane) {
//comp.addMouseListener(mouseListener);
comp.addMouseMotionListener(mouseMotionListener);
}
}
}
dt.setAutoscrolls(true);
final JCheckBox outLineDragMode =
new JCheckBox("Outline Drag Mode");
ActionListener dragModeListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (outLineDragMode.isSelected()) {
dt.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
} else {
dt.setDragMode(JDesktopPane.LIVE_DRAG_MODE);
}
}
};
outLineDragMode.addActionListener(dragModeListener);
JPanel gui = new JPanel(new BorderLayout());
gui.add(outLineDragMode, BorderLayout.PAGE_START);
gui.setBorder(new EmptyBorder(2, 3, 2, 3));
gui.add(new JScrollPane(dt), BorderLayout.CENTER);
JFrame f = new JFrame("DTP Preferred");
f.add(gui);
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See http://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
f.setMinimumSize(f.getSize());
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
printProperty("os.name");
printProperty("java.version");
printProperty("java.vendor");
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
public static void printProperty(String name) {
System.out.println(name + ": \t" + System.getProperty(name));
}
}
怪癖
除了使用
MouseListener
导致问题的 a 之外,它可能会遇到一些怪癖(尚不清楚)。
那时..
- 在完全渲染模式下,桌面窗格将随着用户拖动内部框架(甚至离开 GUI)而动态增长。(好。)在大纲模式下,容器只会在放置时调整大小,而不是拖动。(不太好,但至少滚动条可靠地出现/消失。)