所以基本上我想创建这种GUI,但由于我对Java GUI缺乏经验,我无法弄清楚要使用哪种布局管理器。我已经尝试过Flow,Border,Grid,但是没有一个允许我创建这种GUI而不会弄乱某处的路线。
有什么建议吗?我将来如何决定布局管理器,还是会有经验带来的东西?
我更喜欢使用简单易用的布局,因为这是一个非常基本的GUI,我认为不应该像MiGLayout这样的东西。
答案 0 :(得分:3)
我会使用复合面板和布局的组合。除了更容易使布局工作之外,您还可以在自己的班级中隔离责任区域。
public class TestLayout13 {
public static void main(String[] args) {
new TestLayout13();
}
public TestLayout13() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new FormPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class FormPane extends JPanel {
public FormPane() {
setBorder(new EmptyBorder(8, 8, 8, 8));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
NamePane namePane = new NamePane();
namePane.setBorder(new CompoundBorder(new TitledBorder("Name"), new EmptyBorder(4, 4, 4, 4)));
add(namePane, gbc);
gbc.gridy++;
EMailPane emailPane = new EMailPane();
emailPane.setBorder(new CompoundBorder(new TitledBorder("E-Mail"), new EmptyBorder(4, 4, 4, 4)));
add(emailPane, gbc);
}
}
public class NamePane extends JPanel {
public NamePane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.EAST;
add(new JLabel("First Name:"), gbc);
gbc.gridx += 2;
add(new JLabel("Last Name:"), gbc);
gbc.gridy++;
gbc.gridx = 0;
add(new JLabel("Title:"), gbc);
gbc.gridx += 2;
add(new JLabel("Nickname:"), gbc);
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.WEST;
gbc.weightx = 0.5;
add(new JTextField(10), gbc);
gbc.gridx += 2;
add(new JTextField(10), gbc);
gbc.gridy++;
gbc.gridx = 1;
add(new JTextField(10), gbc);
gbc.gridx += 2;
add(new JTextField(10), gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.anchor = GridBagConstraints.EAST;
gbc.weightx = 0;
gbc.fill = GridBagConstraints.NONE;
add(new JLabel("Format:"), gbc);
gbc.anchor = GridBagConstraints.WEST;
gbc.gridx++;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JComboBox(), gbc);
}
}
protected class EMailPane extends JPanel {
public EMailPane() {
JPanel detailsPane = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.EAST;
detailsPane.add(new JLabel("E-Mail Address:"), gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.WEST;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
detailsPane.add(new JTextField(10), gbc);
gbc.gridy++;
gbc.gridx = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.weighty = 1;
gbc.gridwidth = GridBagConstraints.REMAINDER;
detailsPane.add(new JScrollPane(new JList()), gbc);
JPanel buttonsPane = new JPanel(new GridBagLayout());
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
buttonsPane.add(new JButton("Add"), gbc);
gbc.gridy++;
buttonsPane.add(new JButton("Edit"), gbc);
gbc.gridy++;
buttonsPane.add(new JButton("Delete"), gbc);
gbc.gridy++;
gbc.weighty = 1;
gbc.anchor = GridBagConstraints.NORTH;
buttonsPane.add(new JButton("As Default"), gbc);
JPanel formatPane = new JPanel(new FlowLayout(FlowLayout.LEFT));
formatPane.setBorder(new TitledBorder(new EmptyBorder(1, 1, 1, 1), "Mail Format:"));
formatPane.add(new JRadioButton("HTML"));
formatPane.add(new JRadioButton("Plain"));
formatPane.add(new JRadioButton("Custom"));
setLayout(new BorderLayout());
add(detailsPane);
add(buttonsPane, BorderLayout.LINE_END);
add(formatPane, BorderLayout.PAGE_END);
}
}
}
答案 1 :(得分:2)
我的偏好是MigLayout,因为它是Swing最完整且记录良好的布局管理器。除了Swing之外,它还支持SWT和JavaFX,因此您花在学习它上面的时间可能不止一次。它支持maven,有关详细信息,请参阅http://www.miglayout.com,这是一个很大的优点。它还有一个非常有用的调试功能。您可以在构造函数中添加“debug 1”,然后您将了解如何创建布局。例如:
emailButtonPanel.setLayout(new MigLayout("wrap, fill, insets 20 10 0 10, debug 1"));
我不时发现非常有用的另一个功能是hidemode,它允许您在不可见的情况下(或其他几种策略)组件不参与布局。
以下是使用MigLayout发布的图片的一种可能方法:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import net.miginfocom.layout.CC;
import net.miginfocom.swing.MigLayout;
/**
*/
public class LayoutApproach {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Contact information");
frame.getContentPane().add(new ContactPanel());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setMinimumSize(new Dimension(800, 450));
frame.setLocationRelativeTo(null); // Center
frame.pack();
frame.setVisible(true);
}
});
}
static class ContactPanel extends JPanel {
private JPanel namePanel;
private TitledBorder nameTitledBorder;
private JLabel firstNameLabel;
private JTextField firstNameTextField;
private JLabel lastNameLabel;
private JTextField lastNameTextField;
private JLabel titleLabel;
private JTextField titleTextField;
private JLabel nicknameLabel;
private JTextField nickNameTextField;
private JLabel formatLabel;
private JComboBox<String> formatComboBox;
private JPanel emailPanel;
private TitledBorder emailTitledBorder;
private JLabel emailLabel;
private JTextField emailTextField;
private JList<String> emailItemsList;
private JLabel mailFormatLabel;
private JPanel emailButtonPanel;
private JButton addButton;
private JButton editButton;
private JButton removeButton;
private JButton asDefaultButton;
private JRadioButton htmlRadioButton;
private JRadioButton plainTextRadioButton;
private JRadioButton customTextRadioButton;
private JPanel buttonPanel;
private JButton okButton;
private JButton cancelButton;
public ContactPanel() {
createComponents();
makeLayout();
createHandlers();
registerHandlers();
initComponent();
i18n();
}
/**
* Create GUI components, but contains no layout.
*/
public void createComponents() {
namePanel = new JPanel();
nameTitledBorder = new TitledBorder("");
firstNameLabel = new JLabel();
firstNameTextField = new JTextField();
lastNameLabel = new JLabel();
lastNameTextField = new JTextField();
titleLabel = new JLabel();
titleTextField = new JTextField();
nicknameLabel = new JLabel();
nickNameTextField = new JTextField();
formatLabel = new JLabel();
formatComboBox = new JComboBox<>();
emailPanel = new JPanel();
emailTitledBorder = new TitledBorder("");
emailLabel = new JLabel();
emailTextField = new JTextField();
emailItemsList = new JList<>();
mailFormatLabel = new JLabel();
emailButtonPanel = new JPanel();
addButton = new JButton();
editButton = new JButton();
removeButton = new JButton();
asDefaultButton = new JButton();
htmlRadioButton = new JRadioButton();
plainTextRadioButton = new JRadioButton();
customTextRadioButton = new JRadioButton();
buttonPanel = new JPanel();
okButton = new JButton();
cancelButton = new JButton("Cancel");
}
/**
* Create listeners/handlers
*/
public void createHandlers() {
}
/**
* Registers/adds listeners/handlers.
*/
public void registerHandlers() {
}
public void makeLayout() {
layoutNamePanel();
layoutEmailPanel();
layoutButtonPanel();
MigLayout migLayout = new MigLayout("fill, insets 20");
setLayout(migLayout);
add(namePanel, "dock north");
add(emailPanel, "dock north");
add(buttonPanel, "dock south");
}
private void layoutButtonPanel() {
buttonPanel.setLayout(new MigLayout("alignX right"));
buttonPanel.add(okButton, "tag ok");
buttonPanel.add(cancelButton, "tag cancel");
}
private void layoutNamePanel() {
MigLayout nameLayout = new MigLayout("fill, wrap 4", // Layout Constraints
"15[]15[grow]15[]15[grow]", // Column constraints
""); // Row constraints
// -- Layout all components with name
namePanel.setLayout(nameLayout);
// Create this border here since I use it for layout
Border nameBorder = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10, 6, 10, 6), nameTitledBorder);
namePanel.setBorder(nameBorder);
namePanel.add(firstNameLabel, "alignX right");
namePanel.add(firstNameTextField, "grow");
namePanel.add(lastNameLabel, "alignX right");
namePanel.add(lastNameTextField, "grow");
namePanel.add(titleLabel, "alignX right");
namePanel.add(titleTextField, "grow");
namePanel.add(nicknameLabel, "alignX right");
namePanel.add(nickNameTextField, "grow");
namePanel.add(formatLabel, "alignX right");
namePanel.add(formatComboBox, new CC().grow().span(3)); // Alternative to using plain text'
}
private void layoutEmailPanel() {
MigLayout emailLayout = new MigLayout("fill",// Layout Constraints
"", // Column constraints
""); // Row constraints
// -- Layout all components with name
emailPanel.setLayout(emailLayout);
// Create this border here since I use it for layout
Border emailBorder = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10, 6, 10, 6), emailTitledBorder);
emailPanel.setBorder(emailBorder);
emailButtonPanel.setLayout(new MigLayout("wrap, fill, insets 20 10 0 10"));
emailButtonPanel.add(addButton, "growx");
emailButtonPanel.add(editButton, "growx");
emailButtonPanel.add(removeButton, "growx");
emailButtonPanel.add(asDefaultButton, "growx");
JPanel emailAndItems = new JPanel(new MigLayout("fill"));
emailAndItems.add(emailLabel, "split 2");
emailAndItems.add(emailTextField, "span, growx, wrap");
emailAndItems.add(emailItemsList, "span, grow");
JPanel radioButtons = new JPanel(new MigLayout());
radioButtons.add(htmlRadioButton);
radioButtons.add(plainTextRadioButton);
radioButtons.add(customTextRadioButton);
emailPanel.add(radioButtons, "dock south");
emailPanel.add(mailFormatLabel, "dock south, gapleft 15");
emailPanel.add(emailAndItems, "dock west, growx, push");
emailPanel.add(emailButtonPanel, "dock east, shrink");
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(htmlRadioButton);
buttonGroup.add(plainTextRadioButton);
buttonGroup.add(customTextRadioButton);
}
/**
* Sets initial values for component.
*/
public void initComponent() {
formatComboBox.addItem("Item 1");
formatComboBox.addItem("Item 2");
formatComboBox.addItem("Item 3");
formatComboBox.addItem("Item 4");
DefaultListModel<String> model = new DefaultListModel<>();
emailItemsList.setModel(model);
model.insertElementAt("Item 1", 0);
model.insertElementAt("Item 2", 1);
model.insertElementAt("Item 3", 2);
model.insertElementAt("Item 4", 3);
customTextRadioButton.setSelected(true);
}
public void i18n() {
nameTitledBorder.setTitle("Name:");
firstNameLabel.setText("First Name:");
lastNameLabel.setText("Last Name:");
titleLabel.setText("Title:");
nicknameLabel.setText("Nickname:");
formatLabel.setText("Format:");
emailTitledBorder.setTitle("E-mail");
emailLabel.setText("E-mail address:");
mailFormatLabel.setText("Mail Format:");
addButton.setText("Add");
editButton.setText("Edit");
removeButton.setText("Remove");
asDefaultButton.setText("As Default");
htmlRadioButton.setText("HTML");
plainTextRadioButton.setText("Plain Text");
customTextRadioButton.setText("Custom");
okButton.setText("OK");
cancelButton.setText("Cancel");
}
}
}
代码是用Java 7编写的。与它一起使用的maven pom.xml文件可能是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>stackoverflow</groupId>
<artifactId>stackoverflow</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>com.miglayout</groupId>
<artifactId>miglayout-core</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>com.miglayout</groupId>
<artifactId>miglayout-swing</artifactId>
<version>4.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
答案 2 :(得分:1)
如果您正在寻找Java库布局管理器,我会说边框布局可以正常工作。更高级的是米格布局。你可以谷歌搜索信息。
你知道你可以嵌套布局经理吗?同样,一个JPanel
有一个布局管理器,另一个有不同的布局管理器。所以可以有边框布局和另一种流布局。
答案 3 :(得分:0)
如果您想要一个简单的Swing设计器,可以尝试NetBeans,但是IMHO Miglayout是按照您的意图完成UI的最短方式。在最初的学习曲线之后......当然......
尝试在网格中显示您的屏幕,然后您可以同时使用gridbag和miglayout。