I've searched half the internet and I can't find anybody who has had this same problem.
I've tried several different ways to add a vertical scroll bar, but in vain. Every other post I've seen describing this problem did the following:
JTextArea ta = new JTextArea();
JScrollPane sc = new JScrollPane(ta);
and that seemed to work for them. But I'm out of luck and have tried at least thirty different ways that I've found. I'm new to java and the class I'm in is killing me. Thanks for your time.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Gui extends JFrame
private JTextArea outputArea {
private JButton eastButton;
private JButton westButton;
private JButton northButton;
private JButton southButton;
private JButton helpButton;
private JButton pickupButton;
private JButton dropButton;
private JButton eatButton;
private JButton lookButton;
private JButton listButton;
private JScrollPane scroll;
Gui() {
int x = 0;
int y = 0;
int Width = 1;
int Height = 2;
int anchor;
GridBagConstraints gbc = new GridBagConstraints();
JLabel actionsLabel = null;
JLabel directionsLabel = null;
getContentPane().setBackground(Color.black);
setTitle("Castle Quest");
actionsLabel = new JLabel("Actions");
actionsLabel.setForeground(Color.red);
directionsLabel = new JLabel("Directions");
directionsLabel.setForeground(Color.red);
outputArea = new JTextArea(25, 35);
scroll = new JScrollPane(outputArea);
eastButton = new JButton("east");
eastButton.setSize(100, 30);
westButton = new JButton("west");
westButton.setSize(100, 30);
northButton = new JButton("north");
northButton.setSize(100, 30);
southButton = new JButton("south");
southButton.setSize(100, 30);
helpButton = new JButton("help");
helpButton.setSize(100, 30);
pickupButton = new JButton("pickup");
pickupButton.setSize(100, 30);
dropButton = new JButton("Drop");
dropButton.setSize(100, 30);
eatButton = new JButton("eat");
lookButton = new JButton("look");
lookButton.setSize(100, 30);
listButton = new JButton("list");
listButton.setSize(100, 30);
outputArea.setEditable(true);
GridBagLayout gbl = new GridBagLayout();
setLayout(gbl);
gbc.insets = new Insets(10, 10, 10, 10);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.gridheight = 2;
gbc.anchor = GridBagConstraints.NORTHWEST;
add(actionsLabel, gbc);
gbc.gridy += 2;
add(helpButton, gbc);
gbc.gridy += 2;
add(pickupButton, gbc);
gbc.gridy += 2;
add(dropButton, gbc);
gbc.gridy += 2;
add(eatButton, gbc);
gbc.gridy += 2;
add(lookButton, gbc);
gbc.gridy += 2;
add(listButton, gbc);
gbc.gridy = 1;
gbc.gridx = 2;
gbc.gridheight = 50;
outputArea.setBackground(Color.red);
add(outputArea, gbc);
gbc.gridheight = 2;
gbc.gridx = 3;
gbc.gridy = 1;
add(directionsLabel, gbc);
gbc.gridy = 3;
add(eastButton, gbc);
gbc.gridy += 2;
add(westButton, gbc);
gbc.gridy += 2;
add(northButton, gbc);
gbc.gridy += 2;
add(southButton, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
}
public static void main(String[] args) {
Gui newGame = new Gui();
Game funTime = new Game();
newGame.setSize(400, 150);
newGame.setBackground(Color.black);
newGame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
newGame.pack();
newGame.setVisible(true);
newGame.outputArea.setLineWrap(true);
newGame.outputArea.setWrapStyleWord(true);
newGame.outputArea.append(funTime.getMessage() + "\n");
newGame.eastButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
funTime.move("east");
newGame.outputArea.append(funTime.getMessage() + "\n");
}
});
newGame.westButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
funTime.move("west");
newGame.outputArea.append(funTime.getMessage() + "\n");
}
});
newGame.northButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
funTime.move("north");
newGame.outputArea.append(funTime.getMessage() + "\n");
}
});
newGame.southButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
funTime.move("south");
newGame.outputArea.append(funTime.getMessage() + "\n");
}
});
newGame.helpButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
funTime.getHelp();
newGame.outputArea.append(funTime.getMessage() + "\n");
}
});
newGame.pickupButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (funTime.currentLocation.hasItem()) {
funTime.pickupItem();
newGame.outputArea.append(funTime.getMessage() + "\n");
}
}
});
newGame.listButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < funTime.items.size(); i++) {
System.out.println(funTime.items.get(i));
}
System.out.println(funTime.items);
System.out.println(funTime.currentLocation.getRoomItem1() + " & " + funTime.currentLocation.getRoomItem2());
}
});
}
}
The problem you're facing (the JTextArea expanding) is caused by the fact that you added the JTextArea to the container instead of the JScrollPane.
Here is the logic behind what you should do :
JTextArea is contained by JScrollPane and JScrollPane is contained by the JFrame.
Change this line
add(outputArea, gbc);
to this
add(scroll, gbc);
Related
I am currently trying to include a JTable to my JPanel. I was not having any problems with my code previously until I started to code the table. Sometimes when I run my program everything will appear, sometimes just the panels appear, and sometimes/majority of the time nothing will appear. I just don't understand why it is not consistent. There are no errors in the console. I have included below my ViewPage.java, Page.java, and Main.java.
`
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class ViewPage extends Page implements ActionListener
{
JPanel panel1, panel2, panel3;
JLabel searchLabel, repairsLabel, dateLabel;
JButton goButton, recentButton, oldestButton, homeButton;
JComboBox dropDown;
JTextField textField;
JTable tabel;
JScrollPane scrollpane;
public ViewPage()
{
panel1 = new JPanel();
panel1.setBackground(Color.blue);
panel1.setBounds(0,0,1280,120);
panel2 = new JPanel();
panel2.setBackground(Color.green);
panel2.setBounds(0,120,1280,480);
panel3 = new JPanel();
panel3.setBackground(Color.red);
panel3.setBounds(0,600,1280,120);
//Panel 1 components
repairsLabel = new JLabel("Repairs");
repairsLabel.setFont(new Font("Serif", Font.BOLD, 50));
searchLabel = new JLabel("Search :");
searchLabel.setFont(new Font("Serif", Font.PLAIN, 25));
goButton = new JButton("GO");
goButton.setFocusable(false);
goButton.addActionListener(this);
textField = new JTextField();
String[] filters = {" ", "customerID", "First_Name", "Last_Name"};
dropDown = new JComboBox(filters);
dropDown.addActionListener(this);
panel1.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(1, 10, 1, 0);
gbc.weightx = 5.5;
gbc.gridx = 0;
gbc.gridy = 0;
panel1.add(repairsLabel, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 0.5;
gbc.gridx = 1;
gbc.gridy = 0;
panel1.add(searchLabel, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(1, 10, 1, 50);
gbc.weightx = 3;
gbc.gridx = 2;
gbc.gridy = 0;
panel1.add(dropDown, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(1, 10, 1, 50);
gbc.gridx = 3;
gbc.gridy = 0;
gbc.ipadx = 100;
panel1.add(textField, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(1, 10, 1, 100);
gbc.gridx = 4;
gbc.gridy = 0;
gbc.ipadx = 1;
panel1.add(goButton, gbc);
//Panel 2 components
panel2.setLayout(new GridBagLayout());
String[][] data = new String[50][8];
String[] headings = {"customer_ID", "Date", "First Name", "Last Name", "Phone #", "OS", "PC Type", "Problem"};
JTable table = new JTable(data, headings);
table.setEnabled(false);
table.setPreferredScrollableViewportSize(new Dimension(1000,400));
table.setFillsViewportHeight(true);
scrollpane = new JScrollPane(table);
panel2.add(scrollpane);
//Panel 3 componets
panel3.setLayout(new GridBagLayout());
GridBagConstraints gbc2 = new GridBagConstraints();
dateLabel = new JLabel("Date Filter: ");
dateLabel.setFont(new Font("Serif", Font.PLAIN, 25));
recentButton = new JButton("Most Recent");
oldestButton = new JButton("Oldest");
homeButton = new JButton("Home");
gbc2.fill = GridBagConstraints.HORIZONTAL;
gbc2.insets = new Insets(1, 10, 1, 0);
gbc2.weightx = 5.5;
gbc2.gridx = 0;
gbc2.gridy = 0;
panel3.add(dateLabel, gbc);
frame.add(panel1);
frame.add(panel2);
frame.add(panel3);
}
#Override
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == dropDown)
{
System.out.println(dropDown.getSelectedItem());
}
}
}
`
`
import java.awt.*;
import javax.swing.*;
import javax.swing.border.Border;
public abstract class Page
{
private final static int pageWidth = 1280;
private final static int pageHeight = 720;
protected JFrame frame;
public Page()
{
frame = new JFrame();
frame.setTitle("Computer Repair Store");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(pageWidth, pageHeight);
frame.setLayout(null);
frame.setVisible(true);
}
public int getpageWidth()
{
return pageWidth;
}
public int getpageHeight()
{
return pageHeight;
}
}
`
`
public class Main {
public static void main(String[] args) {
ViewPage viewPage = new ViewPage();
}
}
`
Ouput:
enter image description here
This is what I am expecting to output which has only appeared 2-3 times out of the 50 times I have tried running the program.
enter image description here
I have got a JTextArea and a JTextField and now i want that if i click on JTextArea button the control shifts to JTextArea and
when i click the JTextField button control shifts to JTextField. I am
not getting anything to do such stuff.
The program just changes the text in the JTextField based on the JRadioButton clicked.
***This is the code:***
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class prg_32 extends JPanel implements ItemListener{
JTextArea a1;
JButton t1,t2;
JRadioButton b1,b2,b3,b4;
JTextField fld1;
ButtonGroup grp;
GridBagConstraints gbc = new GridBagConstraints(); //GridBagConstraints object
public prg_32(){
setLayout(new GridBagLayout());
a1 = new JTextArea(3,10); //TextArea
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = 3;
gbc.fill = GridBagConstraints.VERTICAL;
add(a1,gbc); //location of JTextArea
t1 = new JButton("TextArea");
gbc.gridx = 1;
gbc.gridy = 0;
gbc.gridheight = 1;
add(t1,gbc); //location of JButton
t2 = new JButton("TextField");
gbc.gridx = 2;
gbc.gridy = 0;
gbc.gridheight = 1;
add(t2,gbc); //location of JButton
b1 = new JRadioButton("Bold",false);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridheight = 1;
add(b1,gbc);
b2 = new JRadioButton("Italic",false);
gbc.gridx = 2;
gbc.gridy = 1;
gbc.gridheight = 1;
add(b2,gbc);
b3 = new JRadioButton("Plain",false);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.gridheight = 1;
add(b3,gbc);
b4 = new JRadioButton("Bold/Italic",true);
gbc.gridx = 2;
gbc.gridy = 2;
gbc.gridheight = 1;
add(b4,gbc);
grp = new ButtonGroup();
grp.add(b1);
grp.add(b2);
grp.add(b3);
grp.add(b4);
fld1 = new JTextField("enter your name");
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 3;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(fld1,gbc);
fld1.setFont(new Font("Serif",Font.BOLD + Font.ITALIC,14));
b1.addItemListener(this); //Event Handling
b2.addItemListener(this); //Event Handling
b3.addItemListener(this); //Event Handling
b4.addItemListener(this); //Event Handling
}
public void itemStateChanged(ItemEvent e) {
Font font = null;
if(b1.isSelected())
font = new Font("Serif",Font.BOLD,14);
else if(b2.isSelected())
font = new Font("Serif",Font.ITALIC,14);
else if(b3.isSelected())
font = new Font("Serif",Font.PLAIN,14);
else
font = new Font("Serif",Font.BOLD + Font.ITALIC,14);
fld1.setFont(font);
}
public static void main(String[] args){
prg_32 px = new prg_32();
JFrame jf = new JFrame();
jf.setSize(500, 300);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(px);
}
}
I would suggest implementing an ActionListener and using the method Component.requestFocus() in it to set the focus on the text fields.
t1 = new JButton("TextArea");
t1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
a1.requestFocus();
}
});
gbc.gridx = 1;
gbc.gridy = 0;
gbc.gridheight = 1;
add(t1,gbc); //location of JButton
t2 = new JButton("TextField");
t2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
fld1.requestFocus();
}
});
gbc.gridx = 2;
gbc.gridy = 0;
gbc.gridheight = 1;
add(t2,gbc);
I have some JRadioButtons in a ButtonGroup. These are all inside of a container, and there are other items on the group. Whenever I tab to the button group, the focus always goes to the first item in the group. However, I would much rather it go to the item that is selected.
To reproduce the problem, use the code below (add the imports, and for now ignore the fact that I was too lazy to put it all in a SwingUtilities.invokeLater call). Tab down to the radio buttons, and then arrow down to one of the later items, such as Blue. Tab 4 more times to get back to the radio buttons, and you will find the focus on the top "Red" radio button. I would like the focus to be on the "Blue" radio button.
public static void main(String[] args)
{
JFrame f = new JFrame("JRadioButton Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container parent = f.getContentPane();
parent.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.gridx = 1;
gbc.gridy = 1;
parent.add(new JLabel("Start"), gbc);
gbc.gridx++;
parent.add(new JTextField(10), gbc);
gbc.gridx = 1;
gbc.gridy++;
parent.add(new JLabel("End"), gbc);
gbc.gridx++;
parent.add(new JTextField(10), gbc);
gbc.gridx = 1;
gbc.gridy++;
parent.add(new JLabel("Colors"), gbc);
gbc.gridx++;
final Box buttons = Box.createVerticalBox();
parent.add(buttons, gbc);
final ButtonGroup bg = new ButtonGroup();
for (String s : "Red,Orange,Yellow,Green,Blue,Indigo,Violet".split(","))
{
JRadioButton radioBtn = new JRadioButton(s);
buttons.add(radioBtn);
radioBtn.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e)
{
System.out.printf("Itemstate changed to %s\n",
e.getStateChange() == ItemEvent.SELECTED ? "SELECTED" : "DESELECTED");
}
});
radioBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e)
{
System.out.println("JRadioButton action listener");
}
});
bg.add(radioBtn);
}
gbc.gridx = 1;
gbc.gridy += 2;
gbc.gridwidth = 2;
final JLabel currentValue = new JLabel("none");
parent.add(currentValue, gbc);
gbc.gridy--;
JButton btn = new JButton("Show Button Group Value");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e)
{
ButtonModel selection = bg.getSelection();
for (int i = 0; i < buttons.getComponentCount(); i++)
{
JRadioButton radioBtn = (JRadioButton)buttons.getComponent(i);
ButtonModel loopModel = radioBtn.getModel();
if (loopModel == selection)
{
currentValue.setText(radioBtn.getText());
return;
}
currentValue.setText("none");
}
}
});
parent.add(btn, gbc);
f.pack();
f.setVisible(true);
}
You might be able to use a FocusTraversalPolicy:
buttons.setFocusTraversalPolicyProvider(true);
buttons.setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
#Override public Component getDefaultComponent(Container focusCycleRoot) {
ButtonModel selection = bg.getSelection();
for (Component c: focusCycleRoot.getComponents()) {
JRadioButton radioBtn = (JRadioButton) c;
ButtonModel loopModel = radioBtn.getModel();
if (loopModel == selection) {
return radioBtn;
}
}
return super.getDefaultComponent(focusCycleRoot);
}
});
Customizing Focus Traversal: How to Use the Focus Subsystem (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Other Swing Features)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonGroupFocusTraversalTest {
public JComponent makeUI() {
JPanel parent = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.gridx = 1;
gbc.gridy = 1;
parent.add(new JLabel("Start"), gbc);
gbc.gridx++;
parent.add(new JTextField(10), gbc);
gbc.gridx = 1;
gbc.gridy++;
parent.add(new JLabel("End"), gbc);
gbc.gridx++;
JTextField textField = new JTextField(10);
parent.add(textField, gbc);
gbc.gridx = 1;
gbc.gridy++;
parent.add(new JLabel("Colors"), gbc);
gbc.gridx++;
final Box buttons = Box.createVerticalBox();
parent.add(buttons, gbc);
final ButtonGroup bg = new ButtonGroup();
for (String s : "Red,Orange,Yellow,Green,Blue,Indigo,Violet".split(",")) {
JRadioButton radioBtn = new JRadioButton(s);
buttons.add(radioBtn);
bg.add(radioBtn);
}
gbc.gridx = 1;
gbc.gridy += 2;
gbc.gridwidth = 2;
final JLabel currentValue = new JLabel("none");
parent.add(currentValue, gbc);
gbc.gridy--;
JButton btn = new JButton("Show Button Group Value");
parent.add(btn, gbc);
buttons.setFocusTraversalPolicyProvider(true);
buttons.setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
#Override public Component getDefaultComponent(Container focusCycleRoot) {
ButtonModel selection = bg.getSelection();
for (Component c: focusCycleRoot.getComponents()) {
JRadioButton radioBtn = (JRadioButton) c;
ButtonModel loopModel = radioBtn.getModel();
if (loopModel == selection) {
return radioBtn;
}
}
return super.getDefaultComponent(focusCycleRoot);
}
});
return parent;
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new ButtonGroupFocusTraversalTest().makeUI());
f.setSize(320, 320);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
buttonGroup.setFocus(selectedRadioButton);
try this. this set the focus on selectedRadioButton instead of first
I'm currently building a picture sorter. I have a JList which has filenames, to the left of this I have an ImageIcon which should show the picture for the current file_chosen in the JList.
The problem is I can't find a way of updating the ImageIcon contained inside a JLabel; since the change appears inside the anonymous class where the ListSelectionListener() is.
Below is the code:
public class MemeList extends JPanel{
public MemeList(){
// load/update the file list.
updateFileList();
this.setLayout(new GridBagLayout());
JPanel east = new JPanel();
east.setLayout(new GridBagLayout());
gbc.gridx = 1;
gbc.gridy = 0;
this.add(east,gbc);
west = new JPanel();
west.setLayout(new GridBagLayout());
gbc.gridx = 0;
gbc.gridy = 0;
this.add(west,gbc);
filearray = flist.toArray(new String[flist.size()]);
list = new JList(filearray);
list.addListSelectionListener(new ListSelectionListener()
{
#Override
public void valueChanged(ListSelectionEvent e)
{
if (!e.getValueIsAdjusting())
{
file_chosen = (String) list.getSelectedValue();
System.out.println("selected = "+file_chosen);
}
}
});
meme_preview_icon = new ImageIcon(path + "/" + file_chosen); // file_chosen
label2 = new JLabel("", meme_preview_icon, JLabel.CENTER);
gbc.gridx = 0;
gbc.gridy = 0;
west.add(label2,gbc);
updateIcon();
JScrollPane pane = new JScrollPane();
pane.getViewport().add(list);
pane.setPreferredSize(new Dimension(320, 340));
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(0,0,0,0);
east.add(pane, gbc);
}
Below here is the method for changing ImageIcon
public void updateIcon(){
//west.removeAll();
meme_preview_icon = new ImageIcon(path + "/" + file_chosen); // file_chosen
label2.setIcon(meme_preview_icon);
west.revalidate();
west.repaint();
}
I figured out the problem with my flatmate.
I just needed to call the method updateIcon() inside the ListSelectionListener(). I got confused because it told me before it had to be static and then the listener can't be static. But there it is.
list.addListSelectionListener(new ListSelectionListener()
#Override
public void valueChanged(ListSelectionEvent e)
{
if (!e.getValueIsAdjusting())
{
file_chosen = (String) list.getSelectedValue();
System.out.println("selected = "+file_chosen);
updateIcon();
}
}
});
I see that GridBagLayout positions it's children with center alignment within cells. How to align left or right?
UPDATE
Constructing code (I know I could reuse c)
// button panel
JPanel button_panel = new JPanel();
button_panel.add(ok_button);
button_panel.add(cancel_button);
// placing controls to dialog
GridBagConstraints c;
GridBagLayout layout = new GridBagLayout();
setLayout(layout);
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
add(inputSource_label, c);
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 0;
add(inputSource_combo, c);
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 1;
add(output_label, c);
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 1;
add(output_combo, c);
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 2;
add(button_panel, c);
When using GridBagLayout for a tabular display of JLabel : JTextField, I like to have a method that makes my GridBagConstraints for me based on the x, y position. For example something like so:
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.anchor = (x == 0) ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.fill = (x == 0) ? GridBagConstraints.BOTH
: GridBagConstraints.HORIZONTAL;
gbc.insets = (x == 0) ? WEST_INSETS : EAST_INSETS;
gbc.weightx = (x == 0) ? 0.1 : 1.0;
gbc.weighty = 1.0;
return gbc;
}
The following code makes a GUI that looks like this:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
public class GridBagEg {
private static void createAndShowGui() {
PlayerEditorPanel playerEditorPane = new PlayerEditorPanel();
int result = JOptionPane.showConfirmDialog(null, playerEditorPane,
"Edit Player", JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
// TODO: do something with info
for (PlayerEditorPanel.FieldTitle fieldTitle :
PlayerEditorPanel.FieldTitle.values()) {
System.out.printf("%10s: %s%n", fieldTitle.getTitle(),
playerEditorPane.getFieldText(fieldTitle));
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class PlayerEditorPanel extends JPanel {
enum FieldTitle {
NAME("Name"), SPEED("Speed"), STRENGTH("Strength");
private String title;
private FieldTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
};
private static final Insets WEST_INSETS = new Insets(5, 0, 5, 5);
private static final Insets EAST_INSETS = new Insets(5, 5, 5, 0);
private Map<FieldTitle, JTextField> fieldMap = new HashMap<FieldTitle, JTextField>();
public PlayerEditorPanel() {
setLayout(new GridBagLayout());
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Player Editor"),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
GridBagConstraints gbc;
for (int i = 0; i < FieldTitle.values().length; i++) {
FieldTitle fieldTitle = FieldTitle.values()[i];
gbc = createGbc(0, i);
add(new JLabel(fieldTitle.getTitle() + ":", JLabel.LEFT), gbc);
gbc = createGbc(1, i);
JTextField textField = new JTextField(10);
add(textField, gbc);
fieldMap.put(fieldTitle, textField);
}
}
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.anchor = (x == 0) ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.fill = (x == 0) ? GridBagConstraints.BOTH
: GridBagConstraints.HORIZONTAL;
gbc.insets = (x == 0) ? WEST_INSETS : EAST_INSETS;
gbc.weightx = (x == 0) ? 0.1 : 1.0;
gbc.weighty = 1.0;
return gbc;
}
public String getFieldText(FieldTitle fieldTitle) {
return fieldMap.get(fieldTitle).getText();
}
}
In this example, I display the JPanel in a JOptionPane, but it could just as easily be displayed in a JFrame or JApplet or JDialog or ...
For example
public class DimsPanel extends JPanel
{
public static void main(String[] args){
JFrame main = new JFrame("Dims");
JPanel myPanel = new DimsPanel();
main.setContentPane(myPanel);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setSize(400, 400);
main.setLocationRelativeTo(null);
main.setVisible(true);
}
JButton ok_button = new JButton("OK"), cancel_button = new JButton("Cancel");
JLabel inputSource_label = new JLabel("Input source:"),
output_label = new JLabel("Output:");
JComboBox inputSource_combo = new JComboBox(new String[]{"A", "B", "C"}),
output_combo = new JComboBox(new String[]{"A", "B", "C"});
public DimsPanel(){
super(new BorderLayout());
Box main = new Box(BoxLayout.Y_AXIS);
Dimension labelsWidth = new Dimension(100, 0);
JPanel inputPanel = new JPanel(new BorderLayout());
inputSource_label.setPreferredSize(labelsWidth);
inputPanel.add(inputSource_label, BorderLayout.WEST);
inputPanel.add(inputSource_combo);
JPanel outputPanel = new JPanel(new BorderLayout());
output_label.setPreferredSize(labelsWidth);
outputPanel.add(output_label, BorderLayout.WEST);
outputPanel.add(output_combo);
// button panel
JPanel button_panel = new JPanel();
button_panel.add(ok_button);
button_panel.add(cancel_button);
main.add(inputPanel);
main.add(outputPanel);
add(main, BorderLayout.NORTH);
add(button_panel);
}
}
You can run and see it. Resizing works like a charm and the layout code has only 18 lines.
The only disadvantage is that you need to specify the width of the labels by hand. If you really don't want to see setPreferredSize() in the code, then be my guest and go with GridBag. But I personally like this code more.