Предоставление белого пространства в графическом интерфейсе Swing
графический интерфейс без пробелов появляется "переполнен". Как я могу предоставить пустое пространство, не прибегая к явной установке позиции или размера компоненты?
6 ответов:
используя различные
LayoutManagers
можно обеспечить расстояние между различными компонентами.1.) BorderLayout :
- Перегруженный Конструктор :BorderLayout (int horizontalGap, int verticalGap)
методы getter и setter
Для Горизонтального Расстояния :BorderLayout.getHgap () и BorderLayout.setHgap(int hgap)
Для Вертикального Расстояния :BorderLayout.getVgap () и BorderLayout.setVgap ()
2.) FlowLayout :
- Перегруженный Конструктор :FlowLayout(int align, int hgap, int vgap)
методы getter и setter
Для Горизонтального Расстояния : FlowLayout.getHgap () и FlowLayout.setHgap (int hgap)
Для Вертикального Расстояния :FlowLayout.getVgap () и FlowLayout.setVgap ()
3.) GridLayout :
- Перегруженный Конструктор :GridLayout(int rows, int columns, int hgap, int vgap)
геттер и сеттер методы
Для Горизонтального Расстояния :GridLayout.getHgap () и GridLayout.setHgap (int hgap)
Для Вертикального Расстояния :GridLayout.getVgap () и GridLayout.setVgap ()
4.) GridBagLayout :
5.) CardLayout (пример) :
CardLayout (int hGap, int vGap)
Пример отображения всех конструкторов в действии:
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class LayoutExample { private final int hGap = 5; private final int vGap = 5; private String[] borderConstraints = { BorderLayout.PAGE_START, BorderLayout.LINE_START, BorderLayout.CENTER, BorderLayout.LINE_END, BorderLayout.PAGE_END }; private JButton[] buttons; private GridBagConstraints gbc; private JPanel borderPanel; private JPanel flowPanel; private JPanel gridPanel; private JPanel gridBagPanel; private JPanel cardPanel; public LayoutExample() { buttons = new JButton[16]; gbc = new GridBagConstraints(); gbc.anchor = GridBagConstraints.FIRST_LINE_START; gbc.insets = new Insets(hGap, vGap, hGap, vGap); } private void displayGUI() { JFrame frame = new JFrame("Layout Example"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); JPanel contentPane = new JPanel( new GridLayout(0, 1, hGap, vGap)); contentPane.setBorder( BorderFactory.createEmptyBorder(hGap, vGap, hGap, vGap)); borderPanel = new JPanel(new BorderLayout(hGap, vGap)); borderPanel.setBorder( BorderFactory.createTitledBorder("BorderLayout")); borderPanel.setOpaque(true); borderPanel.setBackground(Color.WHITE); for (int i = 0; i < 5; i++) { buttons[i] = new JButton(borderConstraints[i]); borderPanel.add(buttons[i], borderConstraints[i]); } contentPane.add(borderPanel); flowPanel = new JPanel(new FlowLayout( FlowLayout.CENTER, hGap, vGap)); flowPanel.setBorder( BorderFactory.createTitledBorder("FlowLayout")); flowPanel.setOpaque(true); flowPanel.setBackground(Color.WHITE); for (int i = 5; i < 8; i++) { buttons[i] = new JButton(Integer.toString(i)); flowPanel.add(buttons[i]); } contentPane.add(flowPanel); gridPanel = new JPanel(new GridLayout(2, 2, hGap, vGap)); gridPanel.setBorder( BorderFactory.createTitledBorder("GridLayout")); gridPanel.setOpaque(true); gridPanel.setBackground(Color.WHITE); for (int i = 8; i < 12; i++) { buttons[i] = new JButton(Integer.toString(i)); gridPanel.add(buttons[i]); } contentPane.add(gridPanel); gridBagPanel = new JPanel(new GridBagLayout()); gridBagPanel.setBorder( BorderFactory.createTitledBorder("GridBagLayout")); gridBagPanel.setOpaque(true); gridBagPanel.setBackground(Color.WHITE); buttons[12] = new JButton(Integer.toString(12)); addComp(gridBagPanel, buttons[12], 0, 0, 1, 1 , GridBagConstraints.BOTH, 0.33, 0.5); buttons[13] = new JButton(Integer.toString(13)); addComp(gridBagPanel, buttons[13], 1, 0, 1, 1 , GridBagConstraints.BOTH, 0.33, 0.5); buttons[14] = new JButton(Integer.toString(14)); addComp(gridBagPanel, buttons[14], 0, 1, 2, 1 , GridBagConstraints.BOTH, 0.66, 0.5); buttons[15] = new JButton(Integer.toString(15)); addComp(gridBagPanel, buttons[15], 2, 0, 1, 2 , GridBagConstraints.BOTH, 0.33, 1.0); contentPane.add(gridBagPanel); cardPanel = new JPanel(new CardLayout(hGap, vGap)); cardPanel.setBorder( BorderFactory.createTitledBorder("CardLayout")); cardPanel.setOpaque(true); cardPanel.setBackground(Color.WHITE); cardPanel.add(getPanel(Color.BLUE)); cardPanel.add(getPanel(Color.GREEN)); contentPane.add(cardPanel); frame.setContentPane(contentPane); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } private JPanel getPanel(Color bColor) { JPanel panel = new JPanel(new FlowLayout( FlowLayout.CENTER, hGap, vGap)); panel.setOpaque(true); panel.setBackground(bColor.darker().darker()); JButton swapperButton = new JButton("Next"); swapperButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { CardLayout cardLayout = (CardLayout) cardPanel.getLayout(); cardLayout.next(cardPanel); } }); panel.add(swapperButton); return panel; } private void addComp(JPanel panel, JComponent comp , int x, int y, int gWidth , int gHeight, int fill , double weightx, double weighty) { gbc.gridx = x; gbc.gridy = y; gbc.gridwidth = gWidth; gbc.gridheight = gHeight; gbc.fill = fill; gbc.weightx = weightx; gbc.weighty = weighty; panel.add(comp, gbc); } public static void main(String[] args) { Runnable runnable = new Runnable(){ @Override public void run() { new LayoutExample().displayGUI(); } }; EventQueue.invokeLater(runnable); } }
выход :
в графическом интерфейсе Swing есть несколько способов обеспечить разделение между компонентами и пустое пространство вокруг компонентов:
JToolBar
есть методыaddSeparator()
&addSeparator(Dimension)
.JMenu
использует компонент интервала, лучше подходящий для меню, доступных черезaddSeparator()
.но в более общем плане, смотрите:
- расстояние, как можно определить в макете проектировщики.
- границы.
вот пример использования макета разделитель
hGap
&vGap
значения и границы (в частности,EmptyBorder
), чтобы обеспечить "белый" (на самом деле показали, как красный чтобы это было очень очевидно) пространство. Отрегулируйте блесны, чтобы увидеть результат.import java.awt.*; import javax.swing.*; import javax.swing.border.EmptyBorder; import javax.swing.event.*; public class WhiteSpace { private JPanel gui = null; private BorderLayout mainLayout; private FlowLayout buttonLayout; private EmptyBorder border; public Container getGui() { if (gui==null) { mainLayout = new BorderLayout(0,0); gui = new JPanel(mainLayout); gui.setBackground(Color.RED); border = new EmptyBorder(0,0,0,0); JTree tree = new JTree(); tree.setVisibleRowCount(10); for (int ii = tree.getRowCount(); ii>-1; ii--) { tree.expandRow(ii); } gui.add(new JScrollPane( tree, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), BorderLayout.LINE_START); gui.add(new JScrollPane(new JTextArea(10,30))); buttonLayout = new FlowLayout(FlowLayout.CENTER,0,0); JPanel buttonPanel = new JPanel(buttonLayout); gui.add(buttonPanel, BorderLayout.PAGE_START); buttonPanel.add(new JLabel("H Gap")); final JSpinner hSpinner = new JSpinner(new SpinnerNumberModel(0,0,15,1)); buttonPanel.add(hSpinner); buttonPanel.add(new JLabel("V Gap")); final JSpinner vSpinner = new JSpinner(new SpinnerNumberModel(0,0,15,1)); buttonPanel.add(vSpinner); buttonPanel.add(new JLabel("H Border")); final JSpinner hBorderSpinner = new JSpinner(new SpinnerNumberModel(0,0,15,1)); buttonPanel.add(hBorderSpinner); buttonPanel.add(new JLabel("V Border")); final JSpinner vBorderSpinner = new JSpinner(new SpinnerNumberModel(0,0,15,1)); buttonPanel.add(vBorderSpinner); ChangeListener changeListener = new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { int hGap = ((Integer)hSpinner.getValue()).intValue(); int vGap = ((Integer)vSpinner.getValue()).intValue(); int hBorder = ((Integer)hBorderSpinner.getValue()).intValue(); int vBorder = ((Integer)vBorderSpinner.getValue()).intValue(); adjustWhiteSpace(hGap,vGap,hBorder,vBorder); } }; hSpinner.addChangeListener(changeListener); vSpinner.addChangeListener(changeListener); hBorderSpinner.addChangeListener(changeListener); vBorderSpinner.addChangeListener(changeListener); } return gui; } private void adjustWhiteSpace(int hGap, int vGap, int hBorder, int vBorder) { mainLayout.setHgap(hGap); mainLayout.setVgap(vGap); buttonLayout.setHgap(hGap); gui.setBorder(new EmptyBorder(vBorder,hBorder,vBorder,hBorder)); Container c = gui.getTopLevelAncestor(); if (c instanceof Window) { Window w = (Window)c; w.pack(); } } public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { WhiteSpace ws = new WhiteSpace(); // the GUI as seen by the user (without frame) Container gui = ws.getGui(); JFrame f = new JFrame("White (OK Red) Space"); 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.setResizable(false); f.pack(); // should be done last, to avoid flickering, moving, // resizing artifacts. f.setVisible(true); } }; SwingUtilities.invokeLater(r); } }
при использовании
BoxLayout
,Box.createVerticalGlue()
метод может помочь вам сделать некоторые пробелы.другой способ-это
BorderFactory.createEmptyBorder(int top, int left, int bottom, int right)
. Это может помочь вам сделать некоторое пустое пространство вокруг компонента.Спасибо за напоминание Эндрю Томпсона.Я пересмотрел BoxLayout в последние дни, и я считаю, что
Box.createVerticalGlue()
можно добавить некоторые пробелы зависят от размера панели, и вы не можете установить явное значение пикселя длины пробела.НоBox.createVerticalStrut()
можете это сделать. Вот MCTaRE и показать эффект этих двух методов.import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.event.*; public class WhiteSpace extends JFrame{ static WhiteSpace whiteSpace; DemoPanel demoPanel; boolean withGlue; JSpinner spinner; public WhiteSpace(){ initialWindow(); demoPanel = new DemoPanel(); ActionPanel actionPanel = new ActionPanel(); setLayout(new BorderLayout()); getContentPane().add(actionPanel,BorderLayout.NORTH); getContentPane().add(demoPanel,BorderLayout.CENTER); setVisible(true); } public void initialWindow(){ setSize(220, 300); setTitle("White Space"); setResizable(false); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); //Show the window in the middle of the screen } /** * @param args */ public static void main(String[] args) { Runnable runnable = new Runnable() { @Override public void run() { whiteSpace = new WhiteSpace(); } }; SwingUtilities.invokeLater(runnable); } class DemoPanel extends JPanel{ //Show the vertical white space between label1 and label2 JLabel label1; JLabel label2; public void initialDemoPanel(){ setBorder(BorderFactory.createTitledBorder(getBorder(), "DemoPanel", TitledBorder.LEADING, TitledBorder.TOP, new Font("Default",Font.PLAIN,10), Color.gray)); setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); label1 = new JLabel("This is first line"); label2 = new JLabel("This is second line"); } public DemoPanel(){ initialDemoPanel(); add(label1); if(withGlue){ add(Box.createVerticalGlue()); } add(label2); } public DemoPanel(int strutValue){ initialDemoPanel(); add(label1); add(Box.createVerticalStrut(strutValue)); add(label2); } } class ActionPanel extends JPanel{ public ActionPanel(){ setBorder(BorderFactory.createTitledBorder(getBorder(), "ActionPanel", TitledBorder.LEADING, TitledBorder.TOP, new Font("Default",Font.PLAIN,10), Color.gray)); setLayout(new BoxLayout(this,BoxLayout.X_AXIS)); JRadioButton glueButton = new JRadioButton("With Glue"); glueButton.addActionListener(new glueButtonListener()); add(glueButton); add(Box.createHorizontalStrut(10)); //To create horizontal white space JLabel strutLabel = new JLabel("Strut Value"); add(strutLabel); spinner = new JSpinner(new SpinnerNumberModel(0,0,50,1)); spinner.addChangeListener(new spinnerListener()); add(spinner); //public SpinnerNumberModel(Number value,Comparable minimum,Comparable maximum,Number stepSize) } } class glueButtonListener implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { spinner.setValue(new Integer(0)); withGlue = (withGlue == true ? false:true); whiteSpace.getContentPane().remove(demoPanel); demoPanel = new DemoPanel(); whiteSpace.getContentPane().add(demoPanel,BorderLayout.CENTER); whiteSpace.getContentPane().validate(); } } class spinnerListener implements ChangeListener{ @Override public void stateChanged(ChangeEvent e) { int strutValue = (Integer) spinner.getValue(); whiteSpace.getContentPane().remove(demoPanel); demoPanel = new DemoPanel(strutValue); whiteSpace.getContentPane().add(demoPanel,BorderLayout.CENTER); whiteSpace.getContentPane().validate(); } } }
Box.createHorizontalGlue()
иBox.createHorizontalStrut(int height)
можно использовать тоже. Кроме того,Box.createRigidArea(Dimension d)
имеет возможность тоже создавать пустое пространство тоже.
MigLayout
есть несколько способов создания пространства. (Пробел в этом макете называется пробелом.) Пробелы могут быть созданы на самом высоком уровне с ограничениями компоновки, можно создайте зазоры между строками и столбцом и зазоры можно также установить между индивидуалом компоненты с ограничениями на компоненты. Есть также определенные пробелы вокруг границ контейнера под названием insets, которые имеют свое собственное конкретное ключевое слово, которое нужно установить.в следующем примере создаются все эти виды пробелы:
package com.zetcode; import java.awt.EventQueue; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import net.miginfocom.swing.MigLayout; public class MigLayoutGaps2 extends JFrame { public MigLayoutGaps2() { initUI(); setTitle("Gaps"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); } private void initUI() { JPanel base = new JPanel(new MigLayout("flowy, ins 30, gap 15")); setContentPane(base); JPanel pnl1 = new JPanel(); pnl1.setBorder( BorderFactory.createTitledBorder("Grid gaps") ); pnl1.setLayout(new MigLayout("gap 5 5, ins 10, wrap 3")); pnl1.add(new JButton("1")); pnl1.add(new JButton("2")); pnl1.add(new JButton("3")); pnl1.add(new JButton("4")); pnl1.add(new JButton("5")); pnl1.add(new JButton("6")); JPanel pnl2 = new JPanel(); pnl2.setBorder( BorderFactory.createTitledBorder("Column gaps") ); pnl2.setLayout(new MigLayout("wrap 3", "[]10[]")); JLabel lbl1 = new JLabel(); lbl1.setBorder( BorderFactory.createEtchedBorder() ); JLabel lbl2 = new JLabel(); lbl2.setBorder( BorderFactory.createEtchedBorder() ); JLabel lbl3 = new JLabel(); lbl3.setBorder( BorderFactory.createEtchedBorder() ); pnl2.add(lbl1, "w 40, h 110"); pnl2.add(lbl2, "w 40, h 110"); pnl2.add(lbl3, "w 40, h 110"); JPanel pnl3 = new JPanel(); pnl3.setBorder( BorderFactory.createTitledBorder("Row gaps") ); pnl3.setLayout(new MigLayout("wrap", "", "[]15[]")); JLabel lbl4 = new JLabel(); lbl4.setBorder( BorderFactory.createEtchedBorder() ); JLabel lbl5 = new JLabel(); lbl5.setBorder( BorderFactory.createEtchedBorder() ); JLabel lbl6 = new JLabel(); lbl6.setBorder( BorderFactory.createEtchedBorder() ); pnl3.add(lbl4, "w 150, h 20"); pnl3.add(lbl5, "w 150, h 20"); pnl3.add(lbl6, "w 150, h 20"); JPanel pnl4 = new JPanel(); pnl4.setBorder( BorderFactory.createTitledBorder("Component gaps") ); pnl4.setLayout(new MigLayout()); pnl4.add(new JLabel("Name:"), "gapright 5"); pnl4.add(new JTextField(10), "gapbottom 20, gaptop 20"); base.add(pnl1); base.add(pnl2); base.add(pnl3); base.add(pnl4); pack(); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { MigLayoutGaps2 ex = new MigLayoutGaps2(); ex.setVisible(true); } }); } }
у нас есть четыре панели в макете. Каждая из этих панелей имеет
MigLayout
диспетчер.JPanel base = new JPanel(new MigLayout("flowy, ins 30, gap 15"));
эта линия создает вставки контейнера и вертикальные зазоры между панелями.
pnl1.setLayout(new MigLayout("gap 5 5, ins 10, wrap 3"));
здесь мы применяем зазоры для всей структуры сетки, а также устанавливаем зазоры контейнера.
pnl2.setLayout(new MigLayout("wrap 3", "[]10[]"));
эта строка создает промежутки между столбцами.
pnl3.setLayout(new MigLayout("wrap", "", "[]15[]"));
пробелы в строках определяются с помощью этого кода.
pnl4.add(new JLabel("Name:"), "gapright 5"); pnl4.add(new JTextField(10), "gapbottom 20, gaptop 20");
наконец, можно создание зазоров между отдельными компонентами.
автор Lentzsch Карстен-коллекция презентации на дизайн пользовательского интерфейса. В частности это PDF говорит о необходимости эстетический пробел. Добавление значимого пространства, а также обращая внимание на беспорядок отделяет пшеницу от плевел.
всякий раз, когда у меня есть эта проблема, я просто использую JPanels. Например, в GridLayout:
JFrame frame = new JFrame; frame.setLayout(new GridLayout(2, 0)); //We want the bottom left to be blank frame.add(new JLabel("Top Left")); frame.add(new JLabel("Top Right")); //This is the position we want empty frame.add(new JPanel()); //Now we can continue with the rest of the script
надеюсь, что это помогло :)