如何防止Boxlayout / Box拉伸儿童组件?

正如您在下面的runnable代码中看到的,我尝试使用具有可扩展子框的Box。 儿童盒可以改变它们的大小,这一切都很好。 主要问题是大小始终相对于父级。 但我希望它们具有特定的大小,以防万一没有地方使用JScrollPane。 目前他们只收缩其他儿童盒子。

我尝试了Glue和Filler,但它没有用。 胶水没有任何影响,填料具有副作用,始终保持在某些位置(即使ScrollPane正在运行)。 拥有如此多的免费空间真是难看。

所以,你知道防止盒子伸展孩子的好方法吗?

先感谢您!

import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.border.TitledBorder; public class ExpandableMenueDemo { Box allBoxes; ExpandableMenueDemo(){ allBoxes = Box.createVerticalBox(); TitledBorder title; title = BorderFactory.createTitledBorder("Filter"); allBoxes.setBorder(title); for (int i = 0 ;i<3;i++){ //generate collapsable components SubBox b = new SubBox("SubBox"+i); allBoxes.add(b.getSwingBox()); } allBoxes.add(Box.createVerticalGlue()); } public Container getMenue(){ return allBoxes; } public static void main(String[] args) { JFrame frame = new JFrame(); ExpandableMenueDemo m = new ExpandableMenueDemo(); Box mainBox = Box.createHorizontalBox(); mainBox.add(new JScrollPane(m.getMenue())); mainBox.add(new JTable(20,5)); frame.setContentPane(mainBox); frame.pack(); frame.setVisible(true); } class SubBox{ Box box; Box header; String name; JButton cBtn; boolean isCollapsed = true; JLabel headerLine; SubBox(String name) { this.name= name; box = Box.createVerticalBox(); headerLine = new JLabel(name+" () :"); header= Box.createHorizontalBox(); cBtn = new JButton("v"); cBtn.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { if (isCollapsed)show(); else collapse(); } }); collapse(); header.add(cBtn); header.add(Box.createHorizontalStrut(10)); header.add(headerLine); header.add(Box.createHorizontalGlue()); } Box getSwingBox() { Box b = Box.createVerticalBox(); b.add(header); b.add(box); return b; } public void collapse(){ System.out.println("collapse"); box.removeAll(); this.isCollapsed=true; cBtn.setText("v"); } public void show(){ System.out.println("show"); box.removeAll(); this.isCollapsed=false; cBtn.setText("^"); for (int i = 0; i<3;i++) { Box b = Box.createHorizontalBox(); b.add(Box.createHorizontalStrut(20)); b.add(new JCheckBox("checkBox "+i)); b.add(Box.createHorizontalGlue()); box.add(b); } } } } 

您可以考虑使用SwingX中包含的JXTaskPane / -Container,而不是重新发明轮子。 它的演示显示它在左侧的行动(作为taskPanes) – 这是选择演示的部分。

BoxLayout可以接受setXxxSize ,

也许更好的例子来扩展/折叠JPanels嵌套另一个JComponents

在此处输入图像描述

 import java.awt.*; import java.awt.event.*; import java.awt.font.*; import java.awt.image.BufferedImage; import javax.swing.*; public class ExpandingPanels extends MouseAdapter { private ActionPanel[] aps; private JPanel[] panels; public ExpandingPanels() { assembleActionPanels(); assemblePanels(); } @Override public void mousePressed(MouseEvent e) { ActionPanel ap = (ActionPanel) e.getSource(); if (ap.target.contains(e.getPoint())) { ap.toggleSelection(); togglePanelVisibility(ap); } } private void togglePanelVisibility(ActionPanel ap) { int index = getPanelIndex(ap); if (panels[index].isShowing()) { panels[index].setVisible(false); } else { panels[index].setVisible(true); } ap.getParent().validate(); } private int getPanelIndex(ActionPanel ap) { for (int j = 0; j < aps.length; j++) { if (ap == aps[j]) { return j; } } return -1; } private void assembleActionPanels() { String[] ids = {"level 1", "level 2", "level 3", "level 4"}; aps = new ActionPanel[ids.length]; for (int j = 0; j < aps.length; j++) { aps[j] = new ActionPanel(ids[j], this); } } private void assemblePanels() { GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(2, 1, 2, 1); gbc.weightx = 1.0; gbc.weighty = 1.0; JPanel p1 = new JPanel(new GridBagLayout()); gbc.gridwidth = GridBagConstraints.RELATIVE; p1.add(new JButton("button 1"), gbc); gbc.gridwidth = GridBagConstraints.REMAINDER; p1.add(new JButton("button 2"), gbc); gbc.gridwidth = GridBagConstraints.RELATIVE; p1.add(new JButton("button 3"), gbc); gbc.gridwidth = GridBagConstraints.REMAINDER; p1.add(new JButton("button 4"), gbc); JPanel p2 = new JPanel(new GridBagLayout()); gbc.gridwidth = 1; gbc.anchor = GridBagConstraints.EAST; p2.add(new JLabel("enter"), gbc); gbc.anchor = GridBagConstraints.WEST; p2.add(new JTextField(8), gbc); gbc.anchor = GridBagConstraints.CENTER; p2.add(new JButton("button 1"), gbc); gbc.gridwidth = GridBagConstraints.REMAINDER; p2.add(new JButton("button 2"), gbc); JPanel p3 = new JPanel(new BorderLayout()); JTextArea textArea = new JTextArea(8, 12); textArea.setLineWrap(true); p3.add(new JScrollPane(textArea)); JPanel p4 = new JPanel(new GridBagLayout()); addComponents(new JLabel("label 1"), new JTextField(12), p4, gbc); addComponents(new JLabel("label 2"), new JTextField(16), p4, gbc); gbc.gridwidth = 2; gbc.gridy = 2; p4.add(new JSlider(), gbc); gbc.gridy++; JPanel p5 = new JPanel(new GridBagLayout()); p5.add(new JButton("button 1"), gbc); p5.add(new JButton("button 2"), gbc); p5.add(new JButton("button 3"), gbc); p5.add(new JButton("button 4"), gbc); gbc.weighty = 1.0; gbc.fill = GridBagConstraints.BOTH; p4.add(p5, gbc); panels = new JPanel[]{p1, p2, p3, p4}; } private void addComponents(Component c1, Component c2, Container c, GridBagConstraints gbc) { gbc.anchor = GridBagConstraints.EAST; gbc.gridwidth = GridBagConstraints.RELATIVE; c.add(c1, gbc); gbc.anchor = GridBagConstraints.WEST; gbc.gridwidth = GridBagConstraints.REMAINDER; c.add(c2, gbc); gbc.anchor = GridBagConstraints.CENTER; } private JPanel getComponent() { JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(1, 3, 0, 3); gbc.weightx = 1.0; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridwidth = GridBagConstraints.REMAINDER; for (int j = 0; j < aps.length; j++) { panel.add(aps[j], gbc); panel.add(panels[j], gbc); panels[j].setVisible(false); } JLabel padding = new JLabel(); gbc.weighty = 1.0; panel.add(padding, gbc); return panel; } public static void main(String[] args) { Runnable doRun = new Runnable() { @Override public void run() { ExpandingPanels test = new ExpandingPanels(); JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.getContentPane().add(new JScrollPane(test.getComponent())); f.setSize(360, 500); f.setLocation(200, 100); f.setVisible(true); } }; SwingUtilities.invokeLater(doRun); } } class ActionPanel extends JPanel { private static final long serialVersionUID = 1L; private String text; private Font font; private boolean selected; private BufferedImage open, closed; public Rectangle target; final int OFFSET = 30, PAD = 5; ActionPanel(String text, MouseListener ml) { this.text = text; addMouseListener(ml); font = new Font("sans-serif", Font.PLAIN, 12); selected = false; setBackground(new Color(200, 200, 220)); setPreferredSize(new Dimension(200, 20)); setBorder(BorderFactory.createRaisedBevelBorder()); setPreferredSize(new Dimension(200, 20)); createImages(); setRequestFocusEnabled(true); } public void toggleSelection() { selected = !selected; repaint(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int w = getWidth(); int h = getHeight(); if (selected) { g2.drawImage(open, PAD, 0, this); } else { g2.drawImage(closed, PAD, 0, this); } g2.setFont(font); FontRenderContext frc = g2.getFontRenderContext(); LineMetrics lm = font.getLineMetrics(text, frc); float height = lm.getAscent() + lm.getDescent(); float x = OFFSET; float y = (h + height) / 2 - lm.getDescent(); g2.drawString(text, x, y); } private void createImages() { int w = 20; int h = getPreferredSize().height; target = new Rectangle(2, 0, 20, 18); open = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = open.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setPaint(getBackground()); g2.fillRect(0, 0, w, h); int[] x = {2, w / 2, 18}; int[] y = {4, 15, 4}; Polygon p = new Polygon(x, y, 3); g2.setPaint(Color.green.brighter()); g2.fill(p); g2.setPaint(Color.blue.brighter()); g2.draw(p); g2.dispose(); closed = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); g2 = closed.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setPaint(getBackground()); g2.fillRect(0, 0, w, h); x = new int[]{3, 13, 3}; y = new int[]{4, h / 2, 16}; p = new Polygon(x, y, 3); g2.setPaint(Color.red); g2.fill(p); g2.setPaint(Color.blue.brighter()); g2.draw(p); g2.dispose(); } }