我在容器中有三个组件,其中有按钮。当我点击最小化按钮时,组件最小化到容器的底部,当我点击最小化的组件时,它会被最大化。
假设三个组件位于底部,如果我最大化第二个组件,那么它将获得最大化,第三个最小化组件不会占据第二个组件的位置,这仍然是空间。
package Project;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyVetoException;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
import javax.swing.plaf.basic.BasicInternalFrameUI;
public class Test2 {
public Test2() throws HeadlessException, PropertyVetoException {
createAndShowGUI();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
new Test2();
} catch (HeadlessException ex) {
ex.printStackTrace();
} catch (PropertyVetoException ex) {
ex.printStackTrace();
}
}
});
}
private void createAndShowGUI() throws HeadlessException, PropertyVetoException {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
final JDesktopPane jdp = new JDesktopPane() {
@Override
public Dimension getPreferredSize() {
return new Dimension(600, 400);
}
};
frame.setContentPane(jdp);
frame.pack();
createAndAddInternalFrame(jdp, 0, 0);
createAndAddInternalFrame(jdp, 300, 0);
createAndAddInternalFrame(jdp, 1, 200);
frame.setVisible(true);
}
private void createAndAddInternalFrame(final JDesktopPane jdp, int x, int y) throws PropertyVetoException {
final JInternalFrame jInternalFrame = new JInternalFrame("", true, true, true, true);
jInternalFrame.setLocation(x, y);
JPanel jp = new JPanel();
JLabel jl=new JLabel("panel"+x);
JButton jb = new JButton("_");
JButton jb2 = new JButton("[]");
JButton jb3 = new JButton("X");
jInternalFrame.setLayout(new GridLayout(2, 2));
jp.add(jl);
jp.add(jb);
jp.add(jb2);
jp.add(jb3);
jInternalFrame.add(jp);
jb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
try {
if (jInternalFrame.getLayer() == JDesktopPane.FRAME_CONTENT_LAYER) {
jdp.remove(jInternalFrame);
jdp.add(jInternalFrame, JDesktopPane.DEFAULT_LAYER);
jdp.revalidate();
jdp.repaint();
}
jInternalFrame.pack();
jInternalFrame.setIcon(true);
} catch (PropertyVetoException ex) {
ex.printStackTrace();
}
}
});
jb2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
try {
if (jInternalFrame.isMaximum()) {//restore
jInternalFrame.pack();
} else {//maximize
jInternalFrame.setMaximum(true);
}
jdp.remove(jInternalFrame);
jdp.add(jInternalFrame, JDesktopPane.FRAME_CONTENT_LAYER);
jdp.revalidate();
jdp.repaint();
} catch (Exception e) {
e.printStackTrace();
}
}
});
jb3.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
try {
jInternalFrame.dispose();
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
BasicInternalFrameTitlePane titlePane = (BasicInternalFrameTitlePane) ((BasicInternalFrameUI) jInternalFrame.getUI()).getNorthPane();
jInternalFrame.remove(titlePane);
jInternalFrame.pack();
jInternalFrame.setVisible(true);
jdp.repaint();
jdp.add(jInternalFrame);
}
}
答案 0 :(得分:2)
我已经使用Metal和Windows L& F进行了测试,您可能需要与其他人一起测试。
基本上,当组件失效并调用doLayout
方法时,我们会检查是否存在任何JInternalFrame.JDesktopIcon
组件。然后,我们采取这些并按照我们的意愿布置它们......
public class TestInternalFrame {
public static void main(String[] args) {
new TestInternalFrame();
}
private int xpos = 0;
private int ypos = 0;
public TestInternalFrame() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception exp) {
exp.printStackTrace();
}
DesktopPane pane = new DesktopPane();
pane.add(newInternalFrame());
pane.add(newInternalFrame());
pane.add(newInternalFrame());
JFrame frame = new JFrame();
frame.add(pane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public JInternalFrame newInternalFrame() {
JInternalFrame inf = new JInternalFrame("Blah", true, true, true, true);
inf.setLocation(xpos, ypos);
inf.setSize(100, 100);
inf.setVisible(true);
xpos += 50;
ypos += 50;
return inf;
}
public class DesktopPane extends JDesktopPane {
@Override
public void doLayout() {
super.doLayout();
List<Component> icons = new ArrayList<Component>(25);
for (Component comp : getComponents()) {
if (comp instanceof JInternalFrame.JDesktopIcon) {
icons.add(comp);
}
}
int x = 0;
for (Component icon : icons) {
int y = getHeight() - icon.getHeight();
icon.setLocation(x, y);
x += icon.getWidth();
}
}
}
}
毫无疑问,这是一个粗略的黑客
<强>更新强>
int x = 0;
for (Component icon : icons) {
int y = getHeight() - icon.getHeight();
icon.setLocation(x, y);
x += icon.getWidth();
setLayer(icon, 10); // <--- Add me
}
对于您的其他问题,您只需将图标移动到更高的图层即可。这个问题,你实际上需要找到一个足够高的层。你可以使用Integer.MAX_VALUE
,但这有点苛刻(你可能想要一些超过它的东西),相反,你可以计算出最大层并且坐在上面+1 ......
public void doLayout() {
super.doLayout();
List<Component> icons = new ArrayList<Component>(25);
int maxLayer = 0;
for (Component comp : getComponents()) {
if (comp instanceof JInternalFrame.JDesktopIcon) {
icons.add(comp);
maxLayer = Math.max(getLayer(comp), maxLayer);
}
}
maxLayer++;
int x = 0;
for (Component icon : icons) {
int y = getHeight() - icon.getHeight();
icon.setLocation(x, y);
x += icon.getWidth();
setLayer(icon, maxLayer);
}
}
你真的需要花时间学习How to use Internal Frames和How to use Layered Panes,因为(至少最后一部分)已经涵盖在这些......
答案 1 :(得分:1)
类似的东西:
jdp.setDesktopManager( new DefaultDesktopManager(){
@Override
public void deiconifyFrame(JInternalFrame f) {
super.deiconifyFrame(f);
JDesktopPane d = f.getDesktopPane();
JInternalFrame[] frames = d.getAllFrames();
for(JInternalFrame frame : frames ) {
Rectangle bounds = getBoundsForIconOf(frame);
// relayout all frames
}
}
});