我正在尝试获得一个基本的GUI程序。它不需要做太多,但底部的按钮必须工作。我无法将组件(文本,组合框等)放置在适当的位置。使用GridBag我可以使用c.gridx和c.gridy更改位置,但是非常奇怪。如果我将网格值0-7与x为0,则一切都在彼此的顶部。我尝试通过更改gridx值将组合框放在文本旁边,一切都搞砸了。在我试图移动之后,组件上的对齐关闭了。我该如何解决?我没有运气试过BorderLayout.DIRECTION。实际的变化根本没有生效(然后移动到底部)。我该如何解决?感谢
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package javaredesign;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
/**
*
* @author
*/
public class Window extends JFrame {
//Default global variables
private JButton submit;
private JButton cancel;
private JButton reset;
private JPanel panel = new JPanel(new GridBagLayout());
private String searchOutput = "";
//Default constructor
public Window() {
//Title of the window
super("LIBSYS: Search");
//Creating the flow layout to which we can work on and adding panel to frame
setLayout(new FlowLayout());
add(panel, BorderLayout.SOUTH);
//Creating the grid to location of the parts
GridBagConstraints c = new GridBagConstraints();
//Initializing the buttons
submit = new JButton("Submit");
c.insets = new Insets(10, 10, 10, 5);
c.gridx = 1;
c.gridy = 20;
panel.add(submit, c);
reset = new JButton("Reset");
c.gridx = 2;
c.gridy = 20;
panel.add(reset, c);
cancel = new JButton("Cancel");
c.gridx = 3;
c.gridy = 20;
panel.add(cancel, c);
//Handler constructor to do the actionlistening
Handler handler = new Handler();
submit.addActionListener(handler);
reset.addActionListener(handler);
cancel.addActionListener(handler);
//Creating the two dropdowns with the words next to them
JLabel chooseCollection = new JLabel("Choose Collection");
String[] ccString = {"All", "Mostly", "Some", "Few"};
JComboBox ccComboBox = new JComboBox(ccString);
JLabel searchUsing = new JLabel("Search Using");
String[] suString = {"Title", "Artist", "Arthor", "Type"};
JComboBox suComboBox = new JComboBox(suString);
//Adding all the text and dropdown menus to the panel
c.gridx = 0;
c.gridy = 24;
panel.add(chooseCollection, c);
c.gridx = 0;
c.gridy = 25;
panel.add(ccComboBox, c);
c.gridx = 1;
c.gridy = 25;
panel.add(searchUsing, c);
c.gridx = 0;
c.gridy = 27;
panel.add(suComboBox, c);
c.gridx = 1;
c.gridy = 27;
//Setting up the text inputbox
JLabel keyword = new JLabel("Keyword or phrase");
JTextField textField = new JTextField(20);
//Adding lable and text box to the panel
panel.add(keyword);
panel.add(textField);
}
}
答案 0 :(得分:4)
我不会尝试强制按钮与其他组件的布局相同。它们是独立的,应该是均匀自由浮动的。
按钮面板应位于使用 flowlayout 设置的面板中。然后,应将此面板添加到框架中,并在SOUTH处使用 borderlayout 。
其他组件应进入带有 gridbaglayout 的面板,并添加到CENTER的框架中。
然后,gridbaglayout面板应将其所有组件设置在图片中列出的坐标处。如果组件覆盖两个以上的单元格(即组合),则将 gridWidth 属性设置为2.
答案 1 :(得分:2)
问题是您需要了解GridBagLayout
。您需要将组件布局到适当的网格上:
所以你应该有5行12列来布局你在图片中描述的方式。不要介意填充(我试图添加它以使其更具说明性)。前三行应各自包含gridwidth = 6
元素,第一行应位于gridx = 0
,第二行应位于gridx = 6
。然后,您的“是”和“否”按钮应分别在gridwidth = 3
和gridx = 6
处gridx = 9
。最后,您的最后一行(按钮)应分别包含gridwidth = 2
和gridx = 1
,gridx = 5
和gridx = 9
。我只使用gbc.anchor = GridBagConstraints.CENTER
(对于所有组件)而不是使用填充,以便组件在其网格内居中。
我建议将gbc.fill = GridBagConstraints.HORIZONTAL
用于文本字段和组合框,以便它们排列“美观漂亮”,但不要忘记将其设置回gbc.fill = GridBagConstraints.NONE
单选按钮和常规按钮(除非你希望它们也拉伸)。
我非常偶然地改变了你的代码(似乎没有逻辑顺序):
// Creating the grid to location of the parts
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.CENTER;
// Initializing the buttons
submit = new JButton("Submit");
c.insets = new Insets(10, 10, 10, 5);
c.gridx = 1;
c.gridy = 5;
c.gridwidth = 2;
panel.add(submit, c);
reset = new JButton("Reset");
c.gridx = 5;
// c.gridy = 20;
panel.add(reset, c);
cancel = new JButton("Cancel");
c.gridx = 9;
// c.gridy = 20;
panel.add(cancel, c);
// Handler constructor to do the actionlistening
Handler handler = new Handler();
submit.addActionListener(handler);
reset.addActionListener(handler);
cancel.addActionListener(handler);
// Creating the two dropdowns with the words next to them
JLabel chooseCollection = new JLabel("Choose Collection");
String[] ccString = { "All", "Mostly", "Some", "Few" };
JComboBox ccComboBox = new JComboBox(ccString);
JLabel searchUsing = new JLabel("Search Using");
String[] suString = { "Title", "Artist", "Arthor", "Type" };
JComboBox suComboBox = new JComboBox(suString);
// Adding all the text and dropdown menus to the panel
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 6;
c.anchor = GridBagConstraints.WEST;
panel.add(chooseCollection, c);
c.gridx = 6;
// c.gridy = 25;
c.fill = GridBagConstraints.HORIZONTAL;
panel.add(ccComboBox, c);
c.gridx = 0;
c.gridy = 2;
c.fill = GridBagConstraints.NONE;
panel.add(searchUsing, c);
c.gridx = 6;
// c.gridy = 27;
c.fill = GridBagConstraints.HORIZONTAL;
panel.add(suComboBox, c);
// Setting up the text inputbox
JLabel keyword = new JLabel("Keyword or phrase");
JTextField textField = new JTextField(20);
// Adding lable and text box to the panel
c.gridx = 0;
c.gridy = 1;
c.fill = GridBagConstraints.NONE;
panel.add(keyword, c);
c.gridx = 6;
panel.add(textField, c);
其中产生了以下布局:
答案 2 :(得分:2)
我通过外部BorderLayout
来做到这一点。对于标签/控制对,CENTER
将是GroupLayout
。对于按钮,PAGE_END
将是FlowLayout
。
这使用TitledBorder
代替JLabel
来显示LIBSYS Search
。如果它确实需要标签,请将其放在边框布局的PAGE_START
中。
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
import javax.swing.border.*;
public class LibSysSearch {
private JComponent ui = null;
LibSysSearch() {
initUI();
}
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
// Here is our control. This puts a titled border around it,
// instead of using a label in the PAGE_START
JPanel libSysSearchControl = new JPanel(new BorderLayout());
ui.add(libSysSearchControl);
JPanel actionPanel = new JPanel(
new FlowLayout(FlowLayout.CENTER, 15, 15));
libSysSearchControl.add(actionPanel, BorderLayout.PAGE_END);
String[] actionNames = {"Search", "Reset", "Cancel"};
for (String name : actionNames) {
actionPanel.add(new JButton(name));
}
// Use GroupLayout for the label/cotrnl combos.
// make the arrays for the factory method
String[] labels = {
"Choose Collection", "Search Using",
"Keyword or phrase", "Adjacent words"
};
String[] ccString = {"All", "Mostly", "Some", "Few"};
String[] suString = {"Title", "Artist", "Arthor", "Type"};
JPanel confirmAdjacent = new JPanel(new FlowLayout(FlowLayout.LEADING,5,0));
confirmAdjacent.add(new JRadioButton("Yes", true));
confirmAdjacent.add(new JRadioButton("No"));
JComponent[] controls = {
new JComboBox(ccString),
new JTextField(20),
new JComboBox(suString),
confirmAdjacent
};
libSysSearchControl.add(getTwoColumnLayout(labels, controls));
// throw in a few borders for white space
Border border = new CompoundBorder(
new EmptyBorder(10, 10, 10, 10),
new TitledBorder("LIBSYS Search"));
border = new CompoundBorder(
border,
new EmptyBorder(10, 10, 10, 10));
libSysSearchControl.setBorder(border);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
LibSysSearch o = new LibSysSearch();
JFrame f = new JFrame("Library System Search");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
/**
* Provides a JPanel with two columns (labels & fields) laid out using
* GroupLayout. The arrays must be of equal size.
*
* Typical fields would be single line textual/input components such as
* JTextField, JPasswordField, JFormattedTextField, JSpinner, JComboBox,
* JCheckBox.. & the multi-line components wrapped in a JScrollPane -
* JTextArea or (at a stretch) JList or JTable.
*
* @param labels The first column contains labels.
* @param fields The last column contains fields.
* @param addMnemonics Add mnemonic by next available letter in label text.
* @return JComponent A JPanel with two columns of the components provided.
*/
public static JComponent getTwoColumnLayout(
JLabel[] labels,
JComponent[] fields,
boolean addMnemonics) {
if (labels.length != fields.length) {
String s = labels.length + " labels supplied for "
+ fields.length + " fields!";
throw new IllegalArgumentException(s);
}
JComponent panel = new JPanel();
GroupLayout layout = new GroupLayout(panel);
panel.setLayout(layout);
// Turn on automatically adding gaps between components
layout.setAutoCreateGaps(true);
// Create a sequential group for the horizontal axis.
GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
GroupLayout.Group yLabelGroup = layout.createParallelGroup(GroupLayout.Alignment.TRAILING);
hGroup.addGroup(yLabelGroup);
GroupLayout.Group yFieldGroup = layout.createParallelGroup();
hGroup.addGroup(yFieldGroup);
layout.setHorizontalGroup(hGroup);
// Create a sequential group for the vertical axis.
GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
layout.setVerticalGroup(vGroup);
int p = GroupLayout.PREFERRED_SIZE;
// add the components to the groups
for (JLabel label : labels) {
yLabelGroup.addComponent(label);
}
for (Component field : fields) {
yFieldGroup.addComponent(field, p, p, p);
}
for (int ii = 0; ii < labels.length; ii++) {
vGroup.addGroup(layout.createParallelGroup().
addComponent(labels[ii]).
addComponent(fields[ii], p, p, p));
}
if (addMnemonics) {
addMnemonics(labels, fields);
}
return panel;
}
private final static void addMnemonics(
JLabel[] labels,
JComponent[] fields) {
Map<Character, Object> m = new HashMap<Character, Object>();
for (int ii = 0; ii < labels.length; ii++) {
labels[ii].setLabelFor(fields[ii]);
String lwr = labels[ii].getText().toLowerCase();
for (int jj = 0; jj < lwr.length(); jj++) {
char ch = lwr.charAt(jj);
if (m.get(ch) == null && Character.isLetterOrDigit(ch)) {
m.put(ch, ch);
labels[ii].setDisplayedMnemonic(ch);
break;
}
}
}
}
/**
* Provides a JPanel with two columns (labels & fields) laid out using
* GroupLayout. The arrays must be of equal size.
*
* @param labelStrings Strings that will be used for labels.
* @param fields The corresponding fields.
* @return JComponent A JPanel with two columns of the components provided.
*/
public static JComponent getTwoColumnLayout(
String[] labelStrings,
JComponent[] fields) {
JLabel[] labels = new JLabel[labelStrings.length];
for (int ii = 0; ii < labels.length; ii++) {
labels[ii] = new JLabel(labelStrings[ii]);
}
return getTwoColumnLayout(labels, fields);
}
/**
* Provides a JPanel with two columns (labels & fields) laid out using
* GroupLayout. The arrays must be of equal size.
*
* @param labels The first column contains labels.
* @param fields The last column contains fields.
* @return JComponent A JPanel with two columns of the components provided.
*/
public static JComponent getTwoColumnLayout(
JLabel[] labels,
JComponent[] fields) {
return getTwoColumnLayout(labels, fields, true);
}
}
答案 3 :(得分:1)
public class Test {
public Test() {
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel(new GridLayout(0, 1));
JPanel chooseCollectionPanel = new JPanel(new BorderLayout());
JPanel keywordPanel = new JPanel(new BorderLayout());
JPanel searchCategoryPanel = new JPanel(new BorderLayout());
// ...
mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
chooseCollectionPanel.setBorder(BorderFactory.createEmptyBorder(5, 0,
5, 0));
keywordPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
searchCategoryPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5,
0));
JLabel chooseCollectionLabel = new JLabel("Choose Collection: ");
JComboBox<String> chooseCollectionCB = new JComboBox<String>();
chooseCollectionCB.addItem("All");
chooseCollectionPanel.add(chooseCollectionLabel, BorderLayout.WEST);
chooseCollectionPanel.add(chooseCollectionCB, BorderLayout.CENTER);
JLabel chooseCollectionkeywordLabel = new JLabel("Choose Collection: ");
JTextField keywordCB = new JTextField(10);
keywordPanel.add(chooseCollectionkeywordLabel, BorderLayout.WEST);
keywordPanel.add(keywordCB, BorderLayout.CENTER);
// ...
mainPanel.add(chooseCollectionPanel);
mainPanel.add(keywordPanel);
mainPanel.add(searchCategoryPanel);
// ...
frame.add(mainPanel);
frame.setSize(400, 400);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new Test();
}
}