I've tried to use GridBagLayout
. It makes the JTextArea
parent container occupy a big width, but the text area itself didn't fill the width. Why?
And I hope the first button is close to the top and the second button is close to the bottom. How can I implement it?
Could you please advise how to correct my code?
The following code is all code for the demo.
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
public class Demo extends JFrame {
public Demo() throws HeadlessException {
add(new MainPanel());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
class MainPanel extends JPanel {
private final InputComponent inputComponent = new InputComponent();
private final ButtonsContainer buttons = new ButtonsContainer();
public MainPanel() {
setPreferredSize(new Dimension(800, 100));
setLayout(new GridBagLayout());
setBorder(new EmptyBorder(5, 5, 5, 5));
add(inputComponent,
buildConstraints(0, 0, 1, 1, GridConstraints.FILL_BOTH, 1.0, 1.0));
add(buttons,
buildConstraints(1, 0, 1, 1, GridConstraints.FILL_BOTH, 0.0, 1.0));
}
}
class InputComponent extends JComponent {
private final JTextArea textArea = new JTextArea();
public InputComponent() {
setLayout(new BorderLayout());
textArea.setLineWrap(true);
add(textArea, BorderLayout.CENTER);
}
}
class ButtonsContainer extends JComponent {
private final JButton button1 = new JButton("Button 1");
private final JButton button2 = new JButton("Button 2");
public ButtonsContainer() {
setLayout(new GridBagLayout());
add(button1, buildConstraints(0, 0, 1, 1, GridBagConstraints.HORIZONTAL, 1.0, 0.0));
add(button2, buildConstraints(0, 1, 1, 1, GridBagConstraints.HORIZONTAL, 1.0, 0.0));
}
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
final Demo demo = new Demo();
});
}
private GridBagConstraints buildConstraints(
int x,
int y,
int gWidth,
int gHeight,
int fill,
double weightX,
double weightY
) {
final GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = x;
constraints.gridy = y;
constraints.gridwidth = gWidth;
constraints.gridheight = gHeight;
constraints.fill = fill;
constraints.weightx = weightX;
constraints.weighty = weightY;
return constraints;
}
}
CodePudding user response:
Oracle has a helpful tutorial,
Don't extend Swing components, or any other Java class, unless you want to override one or more of the class methods. Use composition over inheritance.
You can use multiple simple JPanels
to create a complex GUI. The GridBagLayout
has its uses, like creating a form. But all that was needed was multiple BorderLayouts
.
Don't make Swing components class fields unless you need to access the field instance from more than one method.
Organize your code so it reads like an essay, with the most important code towards the top and the more detailed code towards the bottom. Ideally, the reader of your code will never have to page up to find out something. No, the compiler doesn't care about the order of the methods. But human readers sure do.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class ExampleBorerLayoutGUI {
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
new ExampleBorerLayoutGUI();
});
}
public ExampleBorerLayoutGUI() {
JFrame frame = new JFrame("");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.add(createButtonPanel(), BorderLayout.EAST);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JTextArea textArea = new JTextArea(5, 40);
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
JScrollPane scrollPane = new JScrollPane(textArea);
panel.add(scrollPane, BorderLayout.CENTER);
return panel;
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JButton button1 = new JButton("Button 1");
panel.add(button1, BorderLayout.NORTH);
JButton button2 = new JButton("Button 2");
panel.add(button2, BorderLayout.SOUTH);
return panel;
}
}
CodePudding user response:
You can auto-generate the right UI code if you use Eclipse IDE's Window Builder: https://www.eclipse.org/windowbuilder/
It is far easier to design your application that way. Set this up on your IDE and let it do the heavy lifting for you. If you wish to incorporate dynamic resizing of your UI elements, design the code to be responsive.