Trying to use Tab to jump between JTextFields vertically (using Custom FocusTraversalPolicy) - java

This is my first database simulator GUI, I'm having a hard time navigating with TAB through the user input text fields. My desire is to navigate in this order: From name to 1st last name, to 2nd last name, to age, to phone number, to address and finally to e-mail. I honestly just copied the code for a custom Focus Traversal Policy and was hoping it would work but it isn't. I don't know if I should even call it on the Listener class or is this redundant?
Here's the code, I'm sorry it got so long =S (omitted libraries to comply w/post max length):
public class UserFormNew {
private JTextField idtf;
private JTextField nametf;
private JTextField ln1tf;
private JTextField ln2tf;
private JTextField agetf;
private JTextField pntf;
private JTextField addresstf;
private JTextField emtf;
private JTable t;
private DefaultTableModel dtm;
private JTableHeader header;
private int idCount = 0;
private int rowSelected;
private boolean ed = false;
private String[] selRowInfoGotten;
private List<Component> compList = new ArrayList<Component>();
private JPanel dataIn;
public UserFormNew() {
// Containers
JFrame mainF = new JFrame();
JPanel mainP = new JPanel(new BorderLayout(10, 5));
dataIn = new JPanel(new GridBagLayout());
JPanel table = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
JPanel buttons = new JPanel(new BorderLayout(20, 10));
// Fonts
Font plain = new Font("Tahoma", Font.PLAIN, 12);
Font plaint = new Font("Tahoma", Font.PLAIN, 11);
Font bold12 = new Font("Tahoma", Font.BOLD, 12);
// Data-In
GridBagConstraints gbc = new GridBagConstraints();
Insets topLeftLabel = new Insets(20, 20, 2, 2);
Insets midLeftLabel = new Insets(2, 20, 2, 2);
Insets botLeftLabel = new Insets(2, 20, 20, 2);
Insets topMidTF = new Insets(20, 2, 2, 20);
Insets midMidTF = new Insets(2, 2, 2, 20);
Insets botMidTF = new Insets(2, 2, 20, 20);
Insets topMidLabel = new Insets(20, 30, 2, 2);
Insets midMidLabel = new Insets(2, 30, 2, 2);
Insets botMidLabel = new Insets(2, 30, 20, 2);
Insets topRightInsets = new Insets(20, 2, 2, 20);
Insets midRightInsets = new Insets(2, 2, 2, 20);
Insets botRightInsets = new Insets(2, 2, 10, 20);
JLabel id = new JLabel("Id");
id.setFont(bold12);
gbc.insets = topLeftLabel;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.weightx = 0.1;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(id, gbc);
JLabel name = new JLabel("Name");
name.setFont(bold12);
gbc.insets = midLeftLabel;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.weightx = 0.1;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(name, gbc);
JLabel ln1 = new JLabel("1\u00B0 Lastname");
ln1.setFont(bold12);
gbc.insets = midLeftLabel;
gbc.gridx = 0;
gbc.gridy = 2;
gbc.gridwidth = 1;
gbc.weightx = 0.1;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(ln1, gbc);
JLabel ln2 = new JLabel("2\u00B0 Lastname");
ln2.setFont(bold12);
gbc.insets = botLeftLabel;
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 1;
gbc.weightx = 0.1;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(ln2, gbc);
JLabel age = new JLabel("Age");
age.setFont(bold12);
gbc.insets = topMidLabel;
gbc.gridx = 2;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.weightx = 0.1;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(age, gbc);
JLabel pn = new JLabel("Phone Number");
pn.setFont(bold12);
gbc.insets = midMidLabel;
gbc.gridx = 2;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.weightx = 0.1;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(pn, gbc);
JLabel address = new JLabel("Address");
address.setFont(bold12);
gbc.insets = midMidLabel;
gbc.gridx = 2;
gbc.gridy = 2;
gbc.gridwidth = 1;
gbc.weightx = 0.1;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(address, gbc);
JLabel em = new JLabel("E-Mail");
em.setFont(bold12);
gbc.insets = botMidLabel;
gbc.gridx = 2;
gbc.gridy = 3;
gbc.gridwidth = 1;
gbc.weightx = 0.1;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(em, gbc);
JLabel emptyTop = new JLabel(" ");
gbc.insets = topRightInsets;
gbc.gridx = 5;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.weightx = 0.7;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(emptyTop, gbc);
JLabel emptyMid1 = new JLabel(" ");
gbc.insets = midRightInsets;
gbc.gridx = 5;
gbc.gridy = 1;
gbc.gridwidth = 2;
gbc.weightx = 0.7;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(emptyMid1, gbc);
JLabel emptyMid2 = new JLabel(" ");
gbc.insets = midRightInsets;
gbc.gridx = 5;
gbc.gridy = 2;
gbc.gridwidth = 2;
gbc.weightx = 0.7;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(emptyMid2, gbc);
JLabel emptyBot = new JLabel(" ");
gbc.insets = botRightInsets;
gbc.gridx = 5;
gbc.gridy = 3;
gbc.gridwidth = 2;
gbc.weightx = 0.7;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(emptyBot, gbc);
idtf = new JTextField("");
idtf.setFont(plain);
idtf.setEditable(false);
idtf.setHorizontalAlignment(JTextField.RIGHT);
idtf.addKeyListener(new NumericList());
gbc.insets = topMidTF;
gbc.gridx = 1;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.weightx = 0.4;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(idtf, gbc);
nametf = new JTextField("");
nametf.setFont(plain);
nametf.setEditable(true);
nametf.addKeyListener(new AlphabeticList());
gbc.insets = midMidTF;
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.weightx = 0.4;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(nametf, gbc);
ln1tf = new JTextField("");
ln1tf.setFont(plain);
ln1tf.setEditable(true);
ln1tf.addKeyListener(new AlphabeticList());
gbc.insets = midMidTF;
gbc.gridx = 1;
gbc.gridy = 2;
gbc.gridwidth = 1;
gbc.weightx = 0.4;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(ln1tf, gbc);
ln2tf = new JTextField("");
ln2tf.setFont(plain);
ln2tf.setEditable(true);
ln2tf.addKeyListener(new AlphabeticList());
gbc.insets = botMidTF;
gbc.gridx = 1;
gbc.gridy = 3;
gbc.gridwidth = 1;
gbc.weightx = 0.4;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(ln2tf, gbc);
agetf = new JTextField("");
agetf.setFont(plain);
agetf.setEditable(true);
agetf.addKeyListener(new NumericList());
gbc.insets = topMidTF;
gbc.gridx = 3;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.weightx = 0.1;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(agetf, gbc);
pntf = new JTextField("");
pntf.setFont(plain);
pntf.setEditable(true);
pntf.addKeyListener(new PhoneList());
gbc.insets = midMidTF;
gbc.gridx = 3;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.weightx = 0.1;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(pntf, gbc);
addresstf = new JTextField("");
addresstf.setFont(plain);
addresstf.setEditable(true);
addresstf.addKeyListener(new AddressList());
gbc.insets = midMidTF;
gbc.gridx = 3;
gbc.gridy = 2;
gbc.gridwidth = 3;
gbc.weightx = 0.7;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(addresstf, gbc);
emtf = new JTextField("");
emtf.setFont(plain);
emtf.setEditable(true);
emtf.addKeyListener(new EmailList());
gbc.insets = botMidTF;
gbc.gridx = 3;
gbc.gridy = 3;
gbc.gridwidth = 3;
gbc.weightx = 0.7;
gbc.weighty = 0.2;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
dataIn.add(emtf, gbc);
// My Traversal Policy
compList.add(nametf);
compList.add(ln1tf);
compList.add(ln2tf);
compList.add(agetf);
compList.add(pntf);
compList.add(addresstf);
compList.add(emtf);
dataIn.setFocusTraversalPolicy(new MyFocusTraversalPolicy());
// Table
String[][] data = {};
String[] headers = { "Id", "Name", "First Lastname", "Second Lastname", "Age", "Phone Number", "Address",
"E-Mail" };
dtm = new DefaultTableModel(data, headers);
t = new JTable(dtm);
t.setFont(plaint);
header = t.getTableHeader();
header.setFont(bold12);
// Table Design
int[] columnsWidth = { 65, 120, 120, 120, 40, 100, 300, 220 };
int i = 0;
for (int width : columnsWidth) {
TableColumn column = t.getColumnModel().getColumn(i++);
column.setMinWidth(width);
column.setMaxWidth(width);
column.setPreferredWidth(width);
}
// Columns Text Alignment
DefaultTableCellRenderer rendererLeft = new DefaultTableCellRenderer();
DefaultTableCellRenderer rendererCenter = new DefaultTableCellRenderer();
TableColumnModel colModel = t.getColumnModel();
TableColumn[] col = new TableColumn[t.getColumnCount()];
for (int j = 0; j < t.getColumnCount(); j++) {
col[j] = colModel.getColumn(j);
switch (j) {
case 0: {
rendererCenter.setHorizontalAlignment(JLabel.CENTER);
col[j].setCellRenderer(rendererCenter);
}
break;
case 1: {
rendererLeft.setHorizontalAlignment(JLabel.LEFT);
col[j].setCellRenderer(rendererLeft);
}
break;
case 2: {
rendererLeft.setHorizontalAlignment(JLabel.LEFT);
col[j].setCellRenderer(rendererLeft);
}
break;
case 3: {
rendererLeft.setHorizontalAlignment(JLabel.LEFT);
col[j].setCellRenderer(rendererLeft);
}
break;
case 4: {
rendererCenter.setHorizontalAlignment(JLabel.CENTER);
col[j].setCellRenderer(rendererCenter);
}
break;
case 5: {
rendererCenter.setHorizontalAlignment(JLabel.CENTER);
col[j].setCellRenderer(rendererCenter);
}
break;
case 6: {
rendererLeft.setHorizontalAlignment(JLabel.LEFT);
col[j].setCellRenderer(rendererLeft);
}
break;
case 7: {
rendererLeft.setHorizontalAlignment(JLabel.LEFT);
col[j].setCellRenderer(rendererLeft);
}
break;
}
}
// Insert table into ScrollPane
JScrollPane sp = new JScrollPane(t);
table.add(sp);
t.setPreferredScrollableViewportSize(new Dimension(1085, 230));
// Buttons
JPanel eastP = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
JButton save = new JButton("Save");
JButton del = new JButton("Delete");
JButton edit = new JButton("Edit");
JButton clr = new JButton("Clear");
save.setFont(bold12);
del.setFont(bold12);
edit.setFont(bold12);
clr.setFont(bold12);
save.addActionListener(new Save());
del.addActionListener(new Delete());
edit.addActionListener(new Edit());
clr.addActionListener(new Clear());
t.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
rowSelected = t.getSelectedRow();
}
});
eastP.add(save);
eastP.add(del);
eastP.add(edit);
eastP.add(clr);
buttons.add(eastP, BorderLayout.EAST);
// Add to main
mainP.add(dataIn, BorderLayout.NORTH);
mainP.add(table, BorderLayout.CENTER);
mainP.add(buttons, BorderLayout.SOUTH);
mainF.setContentPane(mainP);
mainF.pack();
mainF.setVisible(true);
mainF.setResizable(false);
mainF.setLocationRelativeTo(null);
mainF.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new UserFormNew();
}
});
}
//Focus Traversal Policy Custom Class
private class MyFocusTraversalPolicy extends FocusTraversalPolicy {
public Component getComponentAfter(Container focusCycleRoot, Component aComponent) {
int currentPosition = compList.indexOf(aComponent);
currentPosition = (currentPosition + 1) % compList.size();
return (Component) compList.get(currentPosition);
}
public Component getComponentBefore(Container focusCycleRoot, Component aComponent) {
int currentPosition = compList.indexOf(aComponent);
currentPosition = (compList.size() + currentPosition - 1) % compList.size();
return (Component) compList.get(currentPosition);
}
public Component getFirstComponent(Container cntnr) {
return (Component) compList.get(0);
}
public Component getLastComponent(Container cntnr) {
return (Component) compList.get(compList.size() - 1);
}
public Component getDefaultComponent(Container cntnr) {
return (Component) compList.get(0);
}
}
// Listener Classes
public class Save implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
String name = nametf.getText();
String ln1 = ln1tf.getText();
String ln2 = ln2tf.getText();
String age = agetf.getText();
String pn = pntf.getText();
String address = addresstf.getText();
String em = emtf.getText();
// Autogenerate id
idCount++;
// Data Into Table
if (idCount == 0) {
t.setValueAt(Integer.toString(idCount), 0, 0);
t.setValueAt(name, 0, 1);
t.setValueAt(ln1, 0, 2);
t.setValueAt(ln2, 0, 3);
t.setValueAt(age, 0, 4);
t.setValueAt(pn, 0, 5);
t.setValueAt(address, 0, 6);
t.setValueAt(em, 0, 7);
} else if (ed == true) {
t.setValueAt(name, rowSelected, 1);
t.setValueAt(ln1, rowSelected, 2);
t.setValueAt(ln2, rowSelected, 3);
t.setValueAt(age, rowSelected, 4);
t.setValueAt(pn, rowSelected, 5);
t.setValueAt(address, rowSelected, 6);
t.setValueAt(em, rowSelected, 7);
ed = false;
} else {
String[] newRow = { Integer.toString(idCount), name, ln1, ln2, age, pn, address, em };
dtm.addRow(newRow);
}
idtf.setText("");
nametf.setText("");
ln1tf.setText("");
ln2tf.setText("");
agetf.setText("");
pntf.setText("");
addresstf.setText("");
emtf.setText("");
}
}
public class Delete implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
dtm.removeRow(rowSelected);
}
}
public class Edit implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
ed = true;
selRowInfoGotten = new String[t.getColumnCount()];
for (int i = 0; i < t.getColumnCount(); i++) {
selRowInfoGotten[i] = (String) t.getValueAt(rowSelected, i);
}
idtf.setText(selRowInfoGotten[0]);
nametf.setText(selRowInfoGotten[1]);
ln1tf.setText(selRowInfoGotten[2]);
ln2tf.setText(selRowInfoGotten[3]);
agetf.setText(selRowInfoGotten[4]);
pntf.setText(selRowInfoGotten[5]);
addresstf.setText(selRowInfoGotten[6]);
emtf.setText(selRowInfoGotten[7]);
}
}
public class Clear implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (ed == false) {
idtf.setText("");
nametf.setText("");
ln1tf.setText("");
ln2tf.setText("");
agetf.setText("");
pntf.setText("");
addresstf.setText("");
emtf.setText("");
} else {
nametf.setText("");
ln1tf.setText("");
ln2tf.setText("");
agetf.setText("");
pntf.setText("");
addresstf.setText("");
emtf.setText("");
}
}
}
public class AlphabeticList implements KeyListener {
#Override
public void keyTyped(KeyEvent e) {
// Letters only
char testChar = e.getKeyChar();
if (!Character.isAlphabetic(testChar)) {
e.consume();
}
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyChar() == KeyEvent.VK_TAB) {
nametf.getFocusTraversalPolicy();
ln1tf.getFocusTraversalPolicy();
ln2tf.getFocusTraversalPolicy();
}
}
#Override
public void keyReleased(KeyEvent e) { }
}
public class NumericList implements KeyListener {
#Override
public void keyTyped(KeyEvent e) {
// Numbers only
char testChar = e.getKeyChar();
if (!Character.isDigit(testChar)) {
e.consume();
}
// 3-digit ages max
String ageText = agetf.getText();
int ageLength = ageText.length();
if (ageLength >= 3) {
e.consume();
}
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyChar() == KeyEvent.VK_TAB) {
agetf.getFocusTraversalPolicy();
}
}
#Override
public void keyReleased(KeyEvent e) {
}
}
public class AddressList implements KeyListener {
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyChar() == KeyEvent.VK_TAB) {
addresstf.getFocusTraversalPolicy();
}
}
#Override
public void keyReleased(KeyEvent e) {
}
}
public class PhoneList implements KeyListener {
#Override
public void keyTyped(KeyEvent e) {
// Numbers only
char testChar = e.getKeyChar();
if (!Character.isDigit(testChar)) {
e.consume();
}
String pnText = pntf.getText();
int pnLength = pnText.length();
// Add hyphens
if (pnLength == 3 || pnLength == 7) {
pntf.setText(pnText + "-");
}
// 10-digit numbers
if (pnLength >= 12) {
e.consume();
}
// Erase even hyphens
if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
String pnTxt = pntf.getText();
int start = 0;
int end = pnLength - 2;
String pnErased = pnTxt.substring(start, end);
System.out.println(
"PNLength: " + pnLength + ", Start: " + start + ", End: " + end + ", PNErased: " + pnErased);
pntf.setText(pnErased);
}
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyChar() == KeyEvent.VK_TAB) {
pntf.getFocusTraversalPolicy();
}
}
#Override
public void keyReleased(KeyEvent e) {
}
}
public class EmailList implements KeyListener {
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyChar() == KeyEvent.VK_TAB) {
emtf.getFocusTraversalPolicy();
}
}
#Override
public void keyReleased(KeyEvent e) {
}
}
}

Fortunately, I have a much smaller example user form where I added a focus traversal policy.
The code has two parts. While I'm constructing the GUI, I set my focus traversal policy. I put all of the JTextFields into a List in the order that I want them traversed. Every editable field in the JPanel must be included in this List.
I also wrote a class that extends FocusTraversalPolicy. I made it private and included it in the view class. That seems like an appropriate place to put the class. You can put it in a separate file if you want.
Here's the code. You can compile it, run it, and see that tabbing through the form follows the columns. This is what we like to call a minimal, reproducible example.
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FocusTraversalPolicy;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
public class UserForm {
// top, left, bottom, right
private static final Insets topInsets = new Insets(10, 10, 10, 10);
private static final Insets topCenterInsets = new Insets(10, 0, 10, 10);
private static final Insets middleInsets = new Insets(0, 10, 10, 10);
private static final Insets middleCenterInsets = new Insets(0, 0, 10, 10);
public UserForm() {
JFrame frame = new JFrame("User Form");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Miscelaneous
Font plain = new Font("Tahoma", Font.PLAIN, 12);
Font bold11 = new Font("Tahoma", Font.BOLD, 11);
Font bold12 = new Font("Tahoma", Font.BOLD, 12);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridBagLayout());
int gridy = 0;
// Data-In Form Components
JLabel idl = new JLabel("Id:");
idl.setFont(bold12);
addComponent(mainPanel, idl, 0, gridy, 1, 1, topInsets, GridBagConstraints.LINE_START, GridBagConstraints.NONE);
JTextField idtf = new JTextField(40);
idtf.setFont(plain);
addComponent(mainPanel, idtf, 1, gridy, 1, 1, topCenterInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
JLabel agl = new JLabel("Age:");
agl.setFont(bold12);
addComponent(mainPanel, agl, 2, gridy, 1, 1, topCenterInsets, GridBagConstraints.LINE_START,
GridBagConstraints.NONE);
JTextField agtf = new JTextField(40);
agtf.setFont(plain);
addComponent(mainPanel, agtf, 3, gridy++, 1, 1, topCenterInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
JLabel namel = new JLabel("Name:");
namel.setFont(bold12);
addComponent(mainPanel, namel, 0, gridy, 1, 1, middleInsets, GridBagConstraints.LINE_START,
GridBagConstraints.NONE);
JTextField nametf = new JTextField(40);
nametf.setFont(plain);
addComponent(mainPanel, nametf, 1, gridy, 1, 1, middleCenterInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
JLabel adl = new JLabel("Address:");
adl.setFont(bold12);
addComponent(mainPanel, adl, 2, gridy, 1, 1, middleCenterInsets, GridBagConstraints.LINE_START,
GridBagConstraints.NONE);
JTextField adtf = new JTextField(40);
adtf.setFont(plain);
addComponent(mainPanel, adtf, 3, gridy++, 1, 1, middleCenterInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
JLabel pnl = new JLabel("Phone Number:");
pnl.setFont(bold12);
addComponent(mainPanel, pnl, 0, gridy, 1, 1, middleInsets, GridBagConstraints.LINE_START,
GridBagConstraints.NONE);
JTextField pntf = new JTextField(40);
pntf.setFont(plain);
addComponent(mainPanel, pntf, 1, gridy, 1, 1, middleCenterInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
JLabel ln1l = new JLabel("First Lastname:");
ln1l.setFont(bold12);
addComponent(mainPanel, ln1l, 2, gridy, 1, 1, middleCenterInsets, GridBagConstraints.LINE_START,
GridBagConstraints.NONE);
JTextField ln1tf = new JTextField(40);
ln1tf.setFont(plain);
addComponent(mainPanel, ln1tf, 3, gridy++, 1, 1, middleCenterInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
JLabel ln2l = new JLabel("Second Lastname:");
ln2l.setFont(bold12);
addComponent(mainPanel, ln2l, 0, gridy, 1, 1, middleInsets, GridBagConstraints.LINE_START,
GridBagConstraints.NONE);
JTextField ln2tf = new JTextField(40);
ln2tf.setFont(plain);
addComponent(mainPanel, ln2tf, 1, gridy, 1, 1, middleCenterInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
JLabel eml = new JLabel("E-Mail:");
eml.setFont(bold12);
addComponent(mainPanel, eml, 2, gridy, 1, 1, middleCenterInsets, GridBagConstraints.LINE_START,
GridBagConstraints.NONE);
JTextField emtf = new JTextField(40);
emtf.setFont(plain);
addComponent(mainPanel, emtf, 3, gridy++, 1, 1, middleCenterInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
List<Component> order = new ArrayList<>(8);
order.add(idtf);
order.add(nametf);
order.add(pntf);
order.add(ln2tf);
order.add(agtf);
order.add(adtf);
order.add(ln1tf);
order.add(emtf);
MyOwnFocusTraversalPolicy newPolicy = new MyOwnFocusTraversalPolicy(order);
frame.setFocusTraversalPolicy(newPolicy);
// JTable Creation
String[] headline = { "Id", "Name", "First Lastname", "Second Lastname", "Age", "Address", "Phone Number",
"E-Mail" };
String[][] data = { { "", "", "", "", "", "", "", "" }, { "", "", "", "", "", "", "", "" } };
JTable dataShow = new JTable(data, headline);
dataShow.setPreferredScrollableViewportSize(new Dimension(900, 300));
dataShow.setFillsViewportHeight(true);
JScrollPane scrollPane = new JScrollPane(dataShow);
addComponent(mainPanel, scrollPane, 0, gridy++, 4, 1, middleInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
// Table Personalization
dataShow.getTableHeader().setFont(bold11);
new HeaderRenderer(dataShow);
// buttons Components
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridBagLayout());
JButton save = new JButton("Save");
save.setFont(bold12);
addComponent(buttonPanel, save, 0, 0, 1, 1, topInsets, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL);
JButton del = new JButton("Delete");
del.setFont(bold12);
addComponent(buttonPanel, del, 1, 0, 1, 1, topInsets, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
JButton edit = new JButton("Edit");
edit.setFont(bold12);
addComponent(buttonPanel, edit, 2, 0, 1, 1, topInsets, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL);
addComponent(mainPanel, buttonPanel, 0, gridy++, 4, 1, middleInsets, GridBagConstraints.LINE_START,
GridBagConstraints.HORIZONTAL);
// set content pane
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
// For future table filling
/*
* String ids = idtf.getText(); String names = nametf.getText(); String ln1s =
* ln1tf.getText(); String ln2s = ln2tf.getText(); String ags = agtf.getText();
* String ads = adtf.getText(); String pns = pntf.getText(); String ems =
* emtf.getText();
*/
}
private void addComponent(Container container, Component component, int gridx, int gridy, int gridwidth,
int gridheight, Insets insets, int anchor, int fill) {
GridBagConstraints gbc = new GridBagConstraints(gridx, gridy, gridwidth, gridheight, 1.0, 1.0, anchor, fill,
insets, 0, 0);
container.add(component, gbc);
}
public static void main(String[] args) {
// invoke runnable for thread safety
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new UserForm();
}
});
}
// LEFT alignment renderer
private class HeaderRenderer implements TableCellRenderer {
DefaultTableCellRenderer renderer;
public HeaderRenderer(JTable table) {
renderer = (DefaultTableCellRenderer) table.getTableHeader().getDefaultRenderer();
renderer.setHorizontalAlignment(JLabel.LEFT);
}
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int col) {
return renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
}
}
private class MyOwnFocusTraversalPolicy extends FocusTraversalPolicy {
private List<Component> componentList;
public MyOwnFocusTraversalPolicy(List<Component> componentList) {
this.componentList = componentList;
}
#Override
public Component getComponentAfter(Container aContainer, Component aComponent) {
int index = getComponentIndex(aComponent);
index++;
index = (index >= componentList.size()) ? 0 : index;
return componentList.get(index);
}
#Override
public Component getComponentBefore(Container aContainer, Component aComponent) {
int index = getComponentIndex(aComponent);
index--;
index = (index < 0) ? index + componentList.size() : index;
return componentList.get(index);
}
#Override
public Component getFirstComponent(Container aContainer) {
return componentList.get(0);
}
#Override
public Component getLastComponent(Container aContainer) {
return componentList.get(componentList.size() - 1);
}
#Override
public Component getDefaultComponent(Container aContainer) {
return componentList.get(0);
}
private int getComponentIndex(Component test) {
for (int i = 0; i < componentList.size(); i++) {
Component component = componentList.get(i);
if (component.equals(test)) {
return i;
}
}
return -1;
}
}
}

Related

JFrame is not appearing consistently once JTable was added

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

How to position components in a JFrame?

jframe = new JFrame("Admin");
jpanel = new JPanel();
jpanel.setLayout(new FlowLayout());
jframe.add(jpanel);
userLabel = new JLabel("Username:");
jpanel.add(userLabel);
userLabel.setBounds(100, 100, 30, 30);
userTxtfield = new JTextField(15);
jpanel.add(userTxtfield);
passwordTxtfield = new JTextField(15);
jpanel.add(userTxtfield);
jpanel.add(passwordTxtfield);
passwordLabel = new JLabel("Password:");
jpanel.add(passwordLabel);
userLabel.setBounds(100, 100, 30, 30);
loginButton= new JButton("Login");
jpanel.add(loginButton);
jframe.pack();
jframe.setLocationRelativeTo(null);
jframe.setSize(350,350);
jframe.setVisible(true);
I am trying to make a neat login area for my program but I can't seem to get the two labels and text fields to line up with the button underneath. Is there a better way of doing this positioning of the components within this JFrame?
Use a JOptionPane to display a log-in dialog. One way to layout the components is to use a GridBagLayout.
The code that produces that is:
public void login() {
JPanel loginPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints(
0, 0, 1, 1, 0, 0,
GridBagConstraints.BASELINE_TRAILING,
GridBagConstraints.NONE,
new Insets(5, 5, 5, 5), 4, 6);
loginPanel.add(new JLabel("ID"), gbc);
gbc.gridy = 1;
loginPanel.add(new JLabel("Password"), gbc);
gbc.anchor = GridBagConstraints.BASELINE_LEADING;
gbc.gridx = 1;
gbc.gridy = 0;
loginPanel.add(new JTextField("enter ID", 10), gbc);
gbc.gridy = 1;
loginPanel.add(new JPasswordField(6), gbc);
int result = JOptionPane.showConfirmDialog(
ui, loginPanel, "LogIn", JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
// here a real app would check the results of the ID/password
cardLayout.show(ui, "loggedin");
}
}
Here is the complete example (an MCVE, as mentioned above).
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class BlockTheFrame {
private JComponent ui = null;
private CardLayout cardLayout;
BlockTheFrame() {
initUI();
}
public final void initUI() {
if (ui != null) {
return;
}
cardLayout = new CardLayout();
ui = new JPanel(cardLayout);
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
JLabel login = new JLabel("Log in");
login.setFont(login.getFont().deriveFont(200f));
ui.add(login, "login");
ui.add(new JLabel("logged in"), "loggedin");
}
public void login() {
JPanel loginPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints(
0, 0, 1, 1, 0, 0,
GridBagConstraints.BASELINE_TRAILING,
GridBagConstraints.NONE,
new Insets(5, 5, 5, 5), 4, 6);
loginPanel.add(new JLabel("ID"), gbc);
gbc.gridy = 1;
loginPanel.add(new JLabel("Password"), gbc);
gbc.anchor = GridBagConstraints.BASELINE_LEADING;
gbc.gridx = 1;
gbc.gridy = 0;
loginPanel.add(new JTextField("enter ID", 10), gbc);
gbc.gridy = 1;
loginPanel.add(new JPasswordField(6), gbc);
int result = JOptionPane.showConfirmDialog(
ui, loginPanel, "LogIn", JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
// here a real app would check the results of the ID/password
cardLayout.show(ui, "loggedin");
}
}
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) {
}
BlockTheFrame o = new BlockTheFrame();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
o.login();
}
};
SwingUtilities.invokeLater(r);
}
}

JComboBox.setModel keep selection during action

I am going to have some behavior I want to be coupled with some other jcomboboxes, so I am using setModel() to fill in the arrays as values. While doing this and running the gui, I noticed after selecting a different element than the first one, that other element is not showing in the combo box. For example...
As you can see it doesn't say charTwo, even though that is what I selected. Here is the code.
Note: Line#101 is where the setModel() happens...
import org.apache.commons.lang3.ArrayUtils;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
public class TestGui extends JFrame {
private final String[] guiCharSelDefault = {"--- Select Character ---"};
private final String[] characters = {"charOne", "charTwo", "charThree", "charFour"};
private final String[] GuiCharSel = (String[]) ArrayUtils.addAll(guiCharSelDefault, characters);
private JComboBox charCombo = createStandardCombo(GuiCharSel);
private BackgroundPanel backgroundFrame = createBackgroundFrame("../images/Background.png");
private JPanel topFrame = createTopFrame();
private JScrollPane topFrameScroll = createTopScrollPane();
private JPanel centerFrame = createCenterFrame();
//**************************************************************************************
// Constructor
TestGui(){
setContentPane(backgroundFrame);
add(topFrameScroll, BorderLayout.NORTH);
add(centerFrame, BorderLayout.CENTER);
setSize(800,600);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
//**************************************************************************************
// Support Methods
private static GridBagConstraints setGbc(int gridx, int gridy, int gridWidth, int gridHeight, int ipadx, int ipady, String anchorLocation, double weightx, double weighty, Insets insets){
GridBagConstraints gbc = new GridBagConstraints();
if (anchorLocation.toUpperCase().equals("NORTHWEST")){
gbc.anchor = GridBagConstraints.NORTHWEST;
} else if (anchorLocation.toUpperCase().equals("NORTH")){
gbc.anchor = GridBagConstraints.NORTH;
} else if (anchorLocation.toUpperCase().equals("NORTHEAST")){
gbc.anchor = GridBagConstraints.NORTHEAST;
} else if (anchorLocation.toUpperCase().equals("WEST")){
gbc.anchor = GridBagConstraints.WEST;
} else if (anchorLocation.toUpperCase().equals("EAST")){
gbc.anchor = GridBagConstraints.EAST;
} else if (anchorLocation.toUpperCase().equals("SOUTHWEST")){
gbc.anchor = GridBagConstraints.SOUTHWEST;
} else if (anchorLocation.toUpperCase().equals("SOUTH")){
gbc.anchor = GridBagConstraints.SOUTH;
} else if (anchorLocation.toUpperCase().equals("SOUTHEAST")){
gbc.anchor = GridBagConstraints.SOUTHEAST;
} else {
gbc.anchor = GridBagConstraints.CENTER;
}
gbc.gridx = gridx; // column
gbc.gridy = gridy; // row
gbc.gridwidth = gridWidth; // number of columns
gbc.gridheight = gridHeight; // number of rows
gbc.ipadx = ipadx; // width of object
gbc.ipady = ipady; // height of object
gbc.weightx = weightx; // shifts rows to side of set anchor
gbc.weighty = weighty; // shifts columns to side of set anchor
gbc.insets = insets; // placement inside cell
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.fill = GridBagConstraints.VERTICAL;
return gbc;
}
private Insets setInsets(int top, int left, int bottom, int right){
Insets insets = new Insets(top,left,bottom,right);
return insets;
}
//**************************************************************************************
// Interactive Object Methods
private JComboBox createStandardCombo(String[] defaultValues){
JComboBox comboBox = new JComboBox(defaultValues);
DefaultListCellRenderer dlcr = new DefaultListCellRenderer();
dlcr.setHorizontalAlignment(DefaultListCellRenderer.CENTER);
comboBox.setRenderer(dlcr);
comboBox.setPrototypeDisplayValue("X" + guiCharSelDefault + "X");
return comboBox;
}
//**************************************************************************************
// Object Action Methods
private void setCharComboAction(){
charCombo.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
String charName = ((JComboBox)(e.getSource())).getSelectedItem().toString();
if (!(charName.equals(guiCharSelDefault[0]))){
charCombo.setModel(new DefaultComboBoxModel(characters));
}
}
}
);
}
//**************************************************************************************
// Panel Methods
private BackgroundPanel createBackgroundFrame(String imgLocName){
Image backgroundImg = null;
try {
backgroundImg = ImageIO.read(getClass().getResource(imgLocName));
System.out.println("File: " + imgLocName.toString());
} catch (Exception e) {
System.out.println("Cannot read file: " + e);
}
BackgroundPanel bgPanel = new BackgroundPanel(backgroundImg, BackgroundPanel.SCALED, 0.0f, 0.0f);
return bgPanel;
}
private JPanel createTopFrame(){
JPanel pnl = new JPanel();
pnl.setLayout(new GridBagLayout());
setCharComboAction();
pnl.add(charCombo, setGbc(0,0, 1,1, 0,0, "WEST", 0, 0, setInsets(0, 10, 0, 0)));
pnl.setOpaque(false);
return pnl;
}
private JScrollPane createTopScrollPane(){
JScrollPane scrollPane = new JScrollPane(backgroundFrame);
Border raisedBevel = BorderFactory.createRaisedBevelBorder();
Border lineBorder = BorderFactory.createMatteBorder(2, 2, 2, 2, new Color(224,224,224));
Border loweredBevel = BorderFactory.createLoweredBevelBorder();
Border compoundSetup = BorderFactory.createCompoundBorder(raisedBevel, lineBorder);
Border compoundFinal = BorderFactory.createCompoundBorder(compoundSetup, loweredBevel);
scrollPane.setBorder(compoundFinal);
scrollPane.setOpaque(false);
scrollPane.getViewport().setOpaque(false);
scrollPane.getViewport().setView(topFrame);
return scrollPane;
}
private JPanel createCenterFrame() {
JPanel pnl = new JPanel();
Border raisedBevel = BorderFactory.createRaisedBevelBorder();
Color lineColor = new Color(224, 224, 224);
Border lineBorder = BorderFactory.createMatteBorder(5, 5, 5, 5, lineColor);
Border loweredBevel = BorderFactory.createLoweredBevelBorder();
Border compoundSetup = BorderFactory.createCompoundBorder(raisedBevel, lineBorder);
Border compoundFinal = BorderFactory.createCompoundBorder(compoundSetup, loweredBevel);
TitledBorder topFrameTitle = BorderFactory.createTitledBorder(compoundFinal, "Stuff");
topFrameTitle.setTitleJustification(TitledBorder.CENTER);
pnl.setBorder(topFrameTitle);
pnl.setLayout(new GridBagLayout());
pnl.setOpaque(false);
return pnl;
}
//**************************************************************************************
public static void main(String[] args) {
new TestGui();
}
}
Is there a way I can have it keep the selected item after selecting it?
Why you don't restore the selection???
private void setCharComboAction(){
charCombo.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
String charName = ((JComboBox)(e.getSource())).getSelectedItem().toString();
if (!(charName.equals(guiCharSelDefault[0]))){
DefaultComboBoxModel model = new DefaultComboBoxModel(characters);
model.setSelectedItem(charName);
charCombo.setModel(model);
}
}
}
);
}

How to align left or right inside GridBagLayout cell?

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.

How to prevent Boxlayout/Box from stretching children components?

As you can see in the runnable code below, i try to have a Box with expandable child-boxes. The children Boxes can change they size and this all works good. The main problem is that the size is always relative to the parent. But I want them to have a specific size and in case there is no place anymore use the JScrollPane. At the moment they shrink the other children-boxes only.
I tried Glue and Filler, but it didn't work. The glue just had no effect and the filler had the side effect to keep always some place at the (even when the ScrollPane is in action). That is pretty ugly to have there so much free space.
So, do you know a good way to prevent the Boxes from stretching the children?
Thank you in advance!
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.border.TitledBorder;
public class ExpandableMenueDemo {
Box allBoxes;
ExpandableMenueDemo(){
allBoxes = Box.createVerticalBox();
TitledBorder title;
title = BorderFactory.createTitledBorder("Filter");
allBoxes.setBorder(title);
for (int i = 0 ;i<3;i++){
//generate collapsable components
SubBox b = new SubBox("SubBox"+i);
allBoxes.add(b.getSwingBox());
}
allBoxes.add(Box.createVerticalGlue());
}
public Container getMenue(){
return allBoxes;
}
public static void main(String[] args) {
JFrame frame = new JFrame();
ExpandableMenueDemo m = new ExpandableMenueDemo();
Box mainBox = Box.createHorizontalBox();
mainBox.add(new JScrollPane(m.getMenue()));
mainBox.add(new JTable(20,5));
frame.setContentPane(mainBox);
frame.pack();
frame.setVisible(true);
}
class SubBox{
Box box;
Box header;
String name;
JButton cBtn;
boolean isCollapsed = true;
JLabel headerLine;
SubBox(String name) {
this.name= name;
box = Box.createVerticalBox();
headerLine = new JLabel(name+" () :");
header= Box.createHorizontalBox();
cBtn = new JButton("v");
cBtn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
if (isCollapsed)show();
else collapse();
}
});
collapse();
header.add(cBtn);
header.add(Box.createHorizontalStrut(10));
header.add(headerLine);
header.add(Box.createHorizontalGlue());
}
Box getSwingBox() {
Box b = Box.createVerticalBox();
b.add(header);
b.add(box);
return b;
}
public void collapse(){
System.out.println("collapse");
box.removeAll();
this.isCollapsed=true;
cBtn.setText("v");
}
public void show(){
System.out.println("show");
box.removeAll();
this.isCollapsed=false;
cBtn.setText("^");
for (int i = 0; i<3;i++) {
Box b = Box.createHorizontalBox();
b.add(Box.createHorizontalStrut(20));
b.add(new JCheckBox("checkBox "+i));
b.add(Box.createHorizontalGlue());
box.add(b);
}
}
}
}
BoxLayout can accepting setXxxSize,
maybe better example for expanding/collapsing JPanels nests another JComponents
import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class ExpandingPanels extends MouseAdapter {
private ActionPanel[] aps;
private JPanel[] panels;
public ExpandingPanels() {
assembleActionPanels();
assemblePanels();
}
#Override
public void mousePressed(MouseEvent e) {
ActionPanel ap = (ActionPanel) e.getSource();
if (ap.target.contains(e.getPoint())) {
ap.toggleSelection();
togglePanelVisibility(ap);
}
}
private void togglePanelVisibility(ActionPanel ap) {
int index = getPanelIndex(ap);
if (panels[index].isShowing()) {
panels[index].setVisible(false);
} else {
panels[index].setVisible(true);
}
ap.getParent().validate();
}
private int getPanelIndex(ActionPanel ap) {
for (int j = 0; j < aps.length; j++) {
if (ap == aps[j]) {
return j;
}
}
return -1;
}
private void assembleActionPanels() {
String[] ids = {"level 1", "level 2", "level 3", "level 4"};
aps = new ActionPanel[ids.length];
for (int j = 0; j < aps.length; j++) {
aps[j] = new ActionPanel(ids[j], this);
}
}
private void assemblePanels() {
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(2, 1, 2, 1);
gbc.weightx = 1.0;
gbc.weighty = 1.0;
JPanel p1 = new JPanel(new GridBagLayout());
gbc.gridwidth = GridBagConstraints.RELATIVE;
p1.add(new JButton("button 1"), gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
p1.add(new JButton("button 2"), gbc);
gbc.gridwidth = GridBagConstraints.RELATIVE;
p1.add(new JButton("button 3"), gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
p1.add(new JButton("button 4"), gbc);
JPanel p2 = new JPanel(new GridBagLayout());
gbc.gridwidth = 1;
gbc.anchor = GridBagConstraints.EAST;
p2.add(new JLabel("enter"), gbc);
gbc.anchor = GridBagConstraints.WEST;
p2.add(new JTextField(8), gbc);
gbc.anchor = GridBagConstraints.CENTER;
p2.add(new JButton("button 1"), gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
p2.add(new JButton("button 2"), gbc);
JPanel p3 = new JPanel(new BorderLayout());
JTextArea textArea = new JTextArea(8, 12);
textArea.setLineWrap(true);
p3.add(new JScrollPane(textArea));
JPanel p4 = new JPanel(new GridBagLayout());
addComponents(new JLabel("label 1"), new JTextField(12), p4, gbc);
addComponents(new JLabel("label 2"), new JTextField(16), p4, gbc);
gbc.gridwidth = 2;
gbc.gridy = 2;
p4.add(new JSlider(), gbc);
gbc.gridy++;
JPanel p5 = new JPanel(new GridBagLayout());
p5.add(new JButton("button 1"), gbc);
p5.add(new JButton("button 2"), gbc);
p5.add(new JButton("button 3"), gbc);
p5.add(new JButton("button 4"), gbc);
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.BOTH;
p4.add(p5, gbc);
panels = new JPanel[]{p1, p2, p3, p4};
}
private void addComponents(Component c1, Component c2, Container c, GridBagConstraints gbc) {
gbc.anchor = GridBagConstraints.EAST;
gbc.gridwidth = GridBagConstraints.RELATIVE;
c.add(c1, gbc);
gbc.anchor = GridBagConstraints.WEST;
gbc.gridwidth = GridBagConstraints.REMAINDER;
c.add(c2, gbc);
gbc.anchor = GridBagConstraints.CENTER;
}
private JPanel getComponent() {
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(1, 3, 0, 3);
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (int j = 0; j < aps.length; j++) {
panel.add(aps[j], gbc);
panel.add(panels[j], gbc);
panels[j].setVisible(false);
}
JLabel padding = new JLabel();
gbc.weighty = 1.0;
panel.add(padding, gbc);
return panel;
}
public static void main(String[] args) {
Runnable doRun = new Runnable() {
#Override
public void run() {
ExpandingPanels test = new ExpandingPanels();
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new JScrollPane(test.getComponent()));
f.setSize(360, 500);
f.setLocation(200, 100);
f.setVisible(true);
}
};
SwingUtilities.invokeLater(doRun);
}
}
class ActionPanel extends JPanel {
private static final long serialVersionUID = 1L;
private String text;
private Font font;
private boolean selected;
private BufferedImage open, closed;
public Rectangle target;
final int OFFSET = 30,
PAD = 5;
ActionPanel(String text, MouseListener ml) {
this.text = text;
addMouseListener(ml);
font = new Font("sans-serif", Font.PLAIN, 12);
selected = false;
setBackground(new Color(200, 200, 220));
setPreferredSize(new Dimension(200, 20));
setBorder(BorderFactory.createRaisedBevelBorder());
setPreferredSize(new Dimension(200, 20));
createImages();
setRequestFocusEnabled(true);
}
public void toggleSelection() {
selected = !selected;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int w = getWidth();
int h = getHeight();
if (selected) {
g2.drawImage(open, PAD, 0, this);
} else {
g2.drawImage(closed, PAD, 0, this);
}
g2.setFont(font);
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = font.getLineMetrics(text, frc);
float height = lm.getAscent() + lm.getDescent();
float x = OFFSET;
float y = (h + height) / 2 - lm.getDescent();
g2.drawString(text, x, y);
}
private void createImages() {
int w = 20;
int h = getPreferredSize().height;
target = new Rectangle(2, 0, 20, 18);
open = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = open.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(getBackground());
g2.fillRect(0, 0, w, h);
int[] x = {2, w / 2, 18};
int[] y = {4, 15, 4};
Polygon p = new Polygon(x, y, 3);
g2.setPaint(Color.green.brighter());
g2.fill(p);
g2.setPaint(Color.blue.brighter());
g2.draw(p);
g2.dispose();
closed = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
g2 = closed.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(getBackground());
g2.fillRect(0, 0, w, h);
x = new int[]{3, 13, 3};
y = new int[]{4, h / 2, 16};
p = new Polygon(x, y, 3);
g2.setPaint(Color.red);
g2.fill(p);
g2.setPaint(Color.blue.brighter());
g2.draw(p);
g2.dispose();
}
}
Instead of re-inventing the wheel, you might consider to use JXTaskPane/-Container contained in SwingX. Its demo shows it in action (as taskPanes) at the left - that's the part for choosing the demos.

Categories