Get audio file at random from already mapped arraylist - java

Sorry, I have a hitch to fix, I was able to map a File array with a String array, and now, I want to get a random File from the mapped arraylist to play when a button is clicked, but I don't get it.... It doesn't work...
Here's my code:
private static File[] word =
//Here, I announce the contents of the File array named word, about 50 Files
private String []answer =
//String array to be mapped with File array
//Other swing parameters to be used
private static JLabel sound;
private static JButton check;
private static JTextField spell;
private JButton click;
//Font to be used for all text typed in JTextField
private Font fonty;
//Icon to be displayed when sound is played
JLabel icon = new JLabel (new ImageIcon("C:\\Users\\HP\\Pictures\\Photos\\#010.jpg"));
public Quest1() {
// Mapping of String array to File array
Map<String, File> mapping = new HashMap();
Map<String, File>mpl = new HashMap();
mpl.putAll(mapping);
//Layout for the JFrame set (the class extends JFrame)
setLayout (new BorderLayout());
setContentPane(icon);
fonty = new Font("Script MT Bold", Font.PLAIN, 15);
//JPanel to hold swing components
JPanel hold = new JPanel ();
hold.setLayout(new GridBagLayout());
GridBagConstraints g = new GridBagConstraints();
g.anchor = GridBagConstraints.WEST;
g.gridx = 2;
g.gridy = 1;
g.gridwidth = 2;
g.insets = new Insets(2, 20, 2,2);
sound = new JLabel (new ImageIcon("C:\\Users\\HP\\Downloads\\JLabelSoundImage.jpg"));
sound.setPreferredSize(new Dimension(70,70));
hold.add(sound, g);
click = new JButton ("Play");
click.setFont(fonty);
g.anchor = GridBagConstraints.WEST;
g.gridx = 2;
g.gridy = 5;
g.gridwidth = 2;
g.insets = new Insets(2, 20, 8, 2);
hold.add(click, g);
click.addActionListener (new ActionListener (){
public void actionPerformed (ActionEvent t) {
//Where my Problem lies.... getting a random File from the mapped array list to play when the button is clicked.
List key = new ArrayList (mapping.keySet());
Collections.shuffle(key);
for (Object o: key){
mapping.get(o);
InputStream in = new InputStream(mapping.get(o),(word));
}
}
});
spell = new JTextField (10);
spell.setFont(fonty);
g.anchor = GridBagConstraints.EAST;
g.gridx = 5;
g.gridy = 2;
g.gridwidth = 3;
g.insets = new Insets (2, 2, 2, 20);
hold.add (spell, g);
check = new JButton ("Check my answer");
check.setFont(fonty);
g.anchor = GridBagConstraints.SOUTH;
g.gridx = 8;
g.gridy = 8;
g.gridwidth = 3;
g.insets = new Insets (2, 2, 20, 2);
hold.add (check, g);
check.addActionListener (new ActionListener () {
public void actionPerformed (ActionEvent e) {
if (spell.getText().equals(mapping.get(key))) {
String c = "Correct!";
JOptionPane.showMessageDialog(null, c);
}
else {
String d = ("Wrong! the Answer is ") + (mapping.get(key)) ;
JOptionPane.showMessageDialog(null, d);
}
}
});
hold.setVisible(true);
hold.setSize(400,400);
hold.setLocation(50, 50);
hold.setOpaque(false);
add(hold, BorderLayout.CENTER);
}

One problem is not providing the type to your List. This is very risky, so define what type of List it actually is:
List<File> ...
Another problem is mpl.keySet returns a Set, not an ArrayList. You also don't really want to redefine this every time they click the button. Set this Set once, after you've defined your Map.
Set<File> songs = mpl.keySet();
File[] songArray = songs.toArray();
At this point, all you need to do is generate an index and then create a local variable with a reference to the file. This can be done with the Math class.
int index = (int) (Math.random() * songArray.length);
File song = songArray[index];
You may need to add 1 to the index at the end. I don't recall if it will be inclusive or exclusive for all indices.

Related

How do I update a JTable that is an ArrayList?

I was testing an example code that lets people insert their names and the table will fill the name entered along with a seat number.
When the user presses the reserve seat button their name will be added to the table along with the seat number. Everything works except the seat number column. This is my problem I cannot figure out.
int seatNum is set to 1. When the user presses the reserve button, Seat 1 is added to the array list. After that, I wrote to change seatNum to seatNum+1, but this code is ignored. The code will ignore changing the seatNum, which stops the array list from filling, after the code line
seatResArr.set(seatNum, seatElement);.
Can anyone explain how to change the seatNum? If not, please link me a forum with a similar problem as me.
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.JTextField;
public class SeatReservationFrame extends JFrame implements ActionListener {
private JTextField firstNameField; // Holds first name
private JFormattedTextField seatNumField; // Holds seat number
private JLabel tableLabel; // Label for table display
private JLabel seatNumLabel; // Label for seat number
private JLabel firstNameLabel; // Label for first name
private JButton reserveButton; // Triggers seat reservation
private JButton quitButton; // Triggers termination of GUI
private JTable seatStatusTable; // Table tracks seat
reservations
private final static int NUM_SEATS = 5; // Number of seat in reservation system
private static ArrayList<SeatInfo> seatResArr; // ArrayList of Seat objects
/* Constructor creates GUI components and adds GUI components
using a GridBagLayout. */
SeatReservationFrame() {
Object[][] tableVals = new Object[5][2]; // Seat reservation table
String[] columnHeadings = {"Seat Number", "First Name", // Column headings for reservation table
};
GridBagConstraints layoutConst = null; // GUI component layout
// Set frame's title
setTitle("Seat reservation");
// Add 5 seat objects to ArrayList
seatResArr = new ArrayList<SeatInfo>();
seatsAddElements(seatResArr, NUM_SEATS);
// Make all seats empty
seatsMakeEmpty(seatResArr);
// Create seat reservation table
tableLabel = new JLabel("Seat reservation status:");
seatNumLabel = new JLabel("Seat Number:");
firstNameLabel = new JLabel("First Name:");
seatNumField = new JFormattedTextField(NumberFormat.getIntegerInstance());
seatNumField.setEditable(false);
seatNumField.setValue(0);
firstNameField = new JTextField(20);
firstNameField.setEditable(true);
firstNameField.setText("John");
reserveButton = new JButton("Reserve");
reserveButton.addActionListener(this);
quitButton = new JButton("Quit");
quitButton.addActionListener(this);
// Initialize table
seatStatusTable = new JTable(tableVals, columnHeadings);
seatStatusTable.setEnabled(false); // Prevent user input via table
// Add components using GridBagLayout
setLayout(new GridBagLayout());
layoutConst = new GridBagConstraints();
layoutConst.insets = new Insets(10, 10, 1, 0);
layoutConst.fill = GridBagConstraints.HORIZONTAL;
layoutConst.gridx = 0;
layoutConst.gridy = 0;
add(tableLabel, layoutConst);
layoutConst = new GridBagConstraints();
layoutConst.insets = new Insets(1, 10, 0, 0);
layoutConst.fill = GridBagConstraints.HORIZONTAL;
layoutConst.gridx = 0;
layoutConst.gridy = 1;
layoutConst.gridwidth = 4;
add(seatStatusTable.getTableHeader(), layoutConst);
layoutConst = new GridBagConstraints();
layoutConst.insets = new Insets(0, 10, 10, 0);
layoutConst.fill = GridBagConstraints.HORIZONTAL;
layoutConst.gridx = 0;
layoutConst.gridy = 2;
layoutConst.gridwidth = 4;
add(seatStatusTable, layoutConst);
layoutConst = new GridBagConstraints();
layoutConst.insets = new Insets(10, 10, 1, 0);
layoutConst.fill = GridBagConstraints.HORIZONTAL;
layoutConst.gridx = 0;
layoutConst.gridy = 3;
add(seatNumLabel, layoutConst);
layoutConst = new GridBagConstraints();
layoutConst.insets = new Insets(1, 10, 10, 0);
layoutConst.fill = GridBagConstraints.HORIZONTAL;
layoutConst.gridx = 0;
layoutConst.gridy = 4;
add(seatNumField, layoutConst);
layoutConst = new GridBagConstraints();
layoutConst.insets = new Insets(10, 10, 1, 0);
layoutConst.fill = GridBagConstraints.HORIZONTAL;
layoutConst.gridx = 1;
layoutConst.gridy = 3;
add(firstNameLabel, layoutConst);
layoutConst = new GridBagConstraints();
layoutConst.insets = new Insets(1, 10, 10, 0);
layoutConst.fill = GridBagConstraints.HORIZONTAL;
layoutConst.gridx = 1;
layoutConst.gridy = 4;
add(firstNameField, layoutConst);
layoutConst = new GridBagConstraints();
layoutConst.insets = new Insets(0, 10, 10, 5);
layoutConst.fill = GridBagConstraints.HORIZONTAL;
layoutConst.gridx = 4;
layoutConst.gridy = 4;
add(reserveButton, layoutConst);
layoutConst = new GridBagConstraints();
layoutConst.insets = new Insets(0, 5, 10, 10);
layoutConst.fill = GridBagConstraints.HORIZONTAL;
layoutConst.gridx = 5;
layoutConst.gridy = 4;
add(quitButton, layoutConst);
}
/* Called when either button is pressed. */
#Override
public void actionPerformed(ActionEvent event) {
SeatInfo seatElement; // Seat information
String firstName; // First name
int seatNum; // Seat number
// Get source of event (2 buttons in GUI)
JButton sourceEvent = (JButton) event.getSource();
// User pressed the reserve button
if (sourceEvent == reserveButton) {
seatNum = 1;
firstName = firstNameField.getText();
seatElement = new SeatInfo(); // Create new Seat object
seatElement.reserveSeat(firstName);
seatResArr.set(seatNum, seatElement); // Add seat to ArrayList
updateTable(); // Synchronize table with sts ArrayList
seatNum = 4; //!!!!! this code does not work. how can I change the array number?
// Show success dialog
JOptionPane.showMessageDialog(this, "test");
}
else if (sourceEvent == quitButton) {
dispose(); // Terminate program
}
}
/* Updates the reservation information displayed by the table */
public void updateTable() {
final int seatNumCol = 0; // Col num for seat numbers
final int firstNameCol = 1; // Col num for first names
final int lastNameCol = 2; // Col num for last names
final int paidCol = 3; // Col num for amount paid
int i; // Loop index
for (i = 0; i < NUM_SEATS && i < seatResArr.size(); ++i) {
if (seatResArr.get(i).isEmpty()) { // Clear table entries
seatStatusTable.setValueAt(null, i, seatNumCol);
seatStatusTable.setValueAt(null, i, firstNameCol);
}
else { // Update table with content in the seatResArr ArrayList
seatStatusTable.setValueAt(i, i, seatNumCol);
seatStatusTable.setValueAt(seatResArr.get(i).getFirstName(), i, firstNameCol);
}
}
}
/* Makes seats empty */
public static void seatsMakeEmpty(ArrayList<SeatInfo> seatsRes) {
int i; // Loop index
for (i = 0; i < seatsRes.size(); ++i) {
seatsRes.get(i).makeEmpty();
}
}
/* Adds empty seats to ArrayList */
public static void seatsAddElements(ArrayList<SeatInfo> seatsRes, int numSeats) {
int i; // Loop index
for (i = 0; i < numSeats; ++i) {
seatsRes.add(new SeatInfo());
}
}
/* Creates a SeatReservationFrame and makes it visible */
public static void main(String[] args) {
// Creates SeatReservationFrame and its components
SeatReservationFrame myFrame = new SeatReservationFrame();
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.pack();
myFrame.setVisible(true);
}
}
This is the second class that holds the names entered:
public class SeatInfo {
private String firstName; // First name
// Method to initialize Seat fields
public void reserveSeat(String inFirstName) {
firstName = inFirstName;
}
// Method to empty a Seat
public void makeEmpty() {
firstName = "empty";
}
// Method to check if Seat is empty
public boolean isEmpty() {
return firstName.equals("empty");
}
// Method to print Seat fields
public void printSeatInfo() {
System.out.print(firstName + " ");
}
public String getFirstName() {
return firstName;
}
}

How can I make my CE button to take up the entire last row?

All I want is to make my entire last row a single button. Actually, this is a part of my calculator program. I have created another panel for trigonometric calculations. When I remove the sin,cos,tan buttons the calculator doesn't look very good with only a single button on the last row and the rest of the row blank. So after removing the sin,cos,tan buttons I tried to increase the size of the CE button by .setsize(), but in vain. I was hoping if someone could help me with that.
public final class Cal implements ActionListener, KeyListener {
Font font = new Font("SansSerif", Font.BOLD, 32);
JFrame frame = new JFrame();
JPanel panel = new JPanel(new GridLayout(6, 4, 4, 4));
JTextField field = new JTextField("0.0");
JButton[][] keys = new JButton[6][5];
final int plus = 1;
final int minus = 2;
final int times = 3;
final int divide = 4;
final int sin = 5;
final int cos = 6;
final int ce = 7;
final int perc = 8;
int op;
double ans = 0;
double accum = 0;
boolean newNumb = true;
String calc = "";
//Assign method
public void assign() {
frame.setTitle("Scientific Calculator");
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLayout(new BorderLayout());
frame.add(panel, BorderLayout.CENTER);
field.setHorizontalAlignment(JTextField.RIGHT);
field.setEditable(true);
field.setForeground(Color.red);
field.setBackground(Color.white);
field.setToolTipText("Input Box");
field.setFont(font);
frame.add(field, BorderLayout.NORTH);
frame.setVisible(true);
frame.setSize(430, 430);
frame.addKeyListener(this);
// field.addKeyListener(this); //renders field uneditable
field.requestFocus();
panel.setBackground(Color.black);
}
[enter image description here][1]//buttons Method
public void buttons() {
String action;
int i, j;
// create the keys
keys = new JButton[6][5];
keys[0][0] = new JButton("7");
keys[0][1] = new JButton("8");
keys[0][2] = new JButton("9");
keys[0][3] = new JButton("+");
keys[1][0] = new JButton("4");
keys[1][1] = new JButton("5");
keys[1][2] = new JButton("6");
keys[1][3] = new JButton("-");
keys[2][0] = new JButton("1");
keys[2][1] = new JButton("2");
keys[2][2] = new JButton("3");
keys[2][3] = new JButton("x");
keys[3][0] = new JButton("0");
keys[3][1] = new JButton(".");
keys[3][2] = new JButton("=");
keys[3][3] = new JButton("/");
keys[4][0] = new JButton("x³");
keys[4][1] = new JButton("x²");
keys[4][2] = new JButton("%");
keys[4][3] = new JButton("√");
keys[5][0] = new JButton("sin");
keys[5][1] = new JButton("tan");
keys[5][2] = new JButton("cos");
keys[5][3] = new JButton("CE");
//i = rows j =colums
for (i = 0; i < 6; i++) {
for (j = 0; j < 4; j++) {
keys[i][j].setFont(font);
action = (new Integer(i)).toString() + (new Integer(j)).toString();
keys[i][j].setActionCommand(action);
keys[i][j].addActionListener(this);
keys[i][j].setBackground(Color.white);
keys[i][j].setForeground(Color.red);
panel.add(keys[i][j]);
}
}//end of For loops
}

Swing - using GridLayout and JList

Apologies for my code being so messy. I've added and changed and commented out a lot of code and haven't gotten round to cleaning any of it up yet.
My main problem is being confused about how to get a 5x5 set of images. I need to be able to update it regularly as it is a map. These updates are going to happen in a separate method from the main and it will be difficult to know what image is in a particular square - hence why I've made an ArrayList called previous map.
This is so I can remove the elements of the previous map, then add the new ones. This is really ugly though so I'm trying to change the way I'm doing this by using a JList. I don't fully understand it, but it's cropped up in a lot of the examples I've seen.
What I think is happening is that I can add all my 25 images (as JLabel components) to this list, then add this list to the panel I want it to show up in.
I'm also trying to use GridLayout as that's also shown up in a lot of examples. What I think is happening with grid layout is that I set up a 5x5 grid layout, then use setLayout(<GridLayout name>) to the panel I want the grid to be in. I then add the images I want to be in the map to this grid layout.
Is my understanding correct? I've looked at lots of examples and explanations but I'm still unsure. I'm also struggling to understand how I can combine these two ideas - do I have to? If so am I doing it in the right way? If not how would I do this?
So far, I have managed to get this:
However, for some reason,the images are showing up as a column and not in a 5x5 grid.
Here's the relevant code I've been working on:
public class GameGUI3 extends JFrame implements ActionListener
{
private static final long serialVersionUID = 1L;
JFrame f = new JFrame("Dungeons of Doom");
JPanel textPanel = new JPanel();
JPanel leftPanel = new JPanel(new GridBagLayout());
JPanel moveButtonPanel = new JPanel(new GridBagLayout());
JPanel extraButtonPanel = new JPanel(new GridBagLayout());
JPanel mapPanel = new JPanel(new GridBagLayout());
GridLayout gl = new GridLayout(5, 5);
JTextArea textArea = new JTextArea(20, 50);
JScrollPane scrollPane = new JScrollPane(textArea);
DefaultListModel listModel = new DefaultListModel();
JList list = new JList(listModel);
String action;
ArrayList<String> previousMap = new ArrayList<String>();
GridBagConstraints mapC = new GridBagConstraints();
private static GUIClient3 client = new GUIClient3();
JButton n = new JButton("N");
JButton e = new JButton("E");
JButton s = new JButton("S");
JButton w = new JButton("W");
JButton look = new JButton("LOOK");
JButton pickup = new JButton("PICKUP");
JButton hello = new JButton("HELLO");
JButton quit = new JButton("QUIT");
public GameGUI3()
{
GridBagConstraints northC = new GridBagConstraints();
GridBagConstraints eastC = new GridBagConstraints();
GridBagConstraints southC = new GridBagConstraints();
GridBagConstraints westC = new GridBagConstraints();
GridBagConstraints leftTopC = new GridBagConstraints();
GridBagConstraints leftBottomC = new GridBagConstraints(GridBagConstraints extraC = new GridBagConstraints();
northC.insets = new Insets(10, 65, 10, 10);
eastC.insets = new Insets(10, 65, 10, 10);
southC.insets = new Insets(10, 65, 10, 10);
westC.insets = new Insets(10, 0, 10, 10);
leftTopC.insets = new Insets(10, 10, 30, 10);
mapC.insets = new Insets(30, 30, 30, 30);
extraC.insets = new Insets(10, 10, 10, 10);
f.setBounds(100, 100, 1000, 600); // (start on x-axis, start on y, width, height)
textPanel.setBounds(1000, 250, 500, 200);
textPanel.add(new JScrollPane(textArea));
f.getContentPane().add(leftPanel, BorderLayout.WEST);
leftTopC.gridx = 0;
leftTopC.gridy = 0;
leftTopC.anchor = GridBagConstraints.FIRST_LINE_START;
leftPanel.add(moveButtonPanel, leftTopC);
//mapC.gridx = 0;
//mapC.gridy = 1;
//mapC.anchor = GridBagConstraints.LINE_START;
//leftPanel.add(mapPanel, mapC);
//mapPanel.setLayout(gl);
leftPanel.add(mapPanel);
leftBottomC.gridx = 0;
leftBottomC.gridy = 2;
leftBottomC.anchor = GridBagConstraints.LAST_LINE_START;
leftPanel.add(extraButtonPanel, leftBottomC);
f.getContentPane().add(textPanel, BorderLayout.EAST);
textArea.setEditable(false);
this.setVisible(false);
northC.gridx = 0;
northC.gridy = 0;
northC.gridwidth = 3;
northC.anchor = GridBagConstraints.NORTH;
moveButtonPanel.add(n, northC);
westC.gridx = 0;
westC.gridy = 1;
westC.gridwidth = 1;
westC.anchor = GridBagConstraints.WEST;
moveButtonPanel.add(w, westC);
eastC.gridx = 2;
eastC.gridy = 1;
eastC.gridwidth = 3;
eastC.anchor = GridBagConstraints.EAST;
moveButtonPanel.add(e, eastC);
southC.gridx = 0;
southC.gridy = 2;
southC.gridwidth = 3;
southC.anchor = GridBagConstraints.SOUTH;
moveButtonPanel.add(s, southC);
mapC.gridx = 0;
mapC.gridy = 2;
//mapC.gridwidth = 10;
//mapC.anchor = GridBagConstraints.LINE_START;
//mapPanel.setLayout(gl);
leftPanel.add(mapPanel, mapC);
ImageIcon HereBeDragonsIcon = new ImageIcon("HereBeDragons.jpg", "Image");
JLabel HereBeDragonsLabel = new JLabel(HereBeDragonsIcon);
//mapPanel.add(HereBeDragonsLabel);
int count=0;
for(int i=0; i<4; i++)
{
listModel.add(count++, HereBeDragonsIcon);
//listModel.addElement(HereBeDragonsIcon);
previousMap.add("HereBeDragonsLabel");
//mapPanel.add(HereBeDragonsLabel);
}
//JList list = new JList(listModel);
//mapPanel.add(list);
mapPanel.add(list);
extraButtonPanel.add(look, extraC);
extraButtonPanel.add(pickup, extraC);
extraButtonPanel.add(hello, extraC);
extraButtonPanel.add(quit, extraC);
n.addActionListener(this);
e.addActionListener(this);
s.addActionListener(this);
w.addActionListener(this);
look.addActionListener(this);
pickup.addActionListener(this);
hello.addActionListener(this);
quit.addActionListener(this);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.pack();
f.setVisible(true);
}
Many thanks - if anything is unclear please let me know and I will try and re-phrase my question or explain my code better.

JPanel component placement

I am trying to get a basic GUI program. It doesnt have to do much but the buttons at the bottom have to work. I am having trouble placing the components (The text, combobox, etc) in the proper spot. Using the GridBag I am able to change the location with the c.gridx and c.gridy but in a very weird way. If I put the gridy values 0-7 with x being 0 everything is on top of eachother. I try putting the combo box next to the text by changing the gridx value and everything gets messed up. The alignment is off on the components after the one I was trying to move over. How do I fix this? I tried the BorderLayout.DIRECTION with no luck. The actual change doesn't take effect at all (moving then to the bottom). How do I fix this? Thanks
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package javaredesign;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
/**
*
* #author
*/
public class Window extends JFrame {
//Default global variables
private JButton submit;
private JButton cancel;
private JButton reset;
private JPanel panel = new JPanel(new GridBagLayout());
private String searchOutput = "";
//Default constructor
public Window() {
//Title of the window
super("LIBSYS: Search");
//Creating the flow layout to which we can work on and adding panel to frame
setLayout(new FlowLayout());
add(panel, BorderLayout.SOUTH);
//Creating the grid to location of the parts
GridBagConstraints c = new GridBagConstraints();
//Initializing the buttons
submit = new JButton("Submit");
c.insets = new Insets(10, 10, 10, 5);
c.gridx = 1;
c.gridy = 20;
panel.add(submit, c);
reset = new JButton("Reset");
c.gridx = 2;
c.gridy = 20;
panel.add(reset, c);
cancel = new JButton("Cancel");
c.gridx = 3;
c.gridy = 20;
panel.add(cancel, c);
//Handler constructor to do the actionlistening
Handler handler = new Handler();
submit.addActionListener(handler);
reset.addActionListener(handler);
cancel.addActionListener(handler);
//Creating the two dropdowns with the words next to them
JLabel chooseCollection = new JLabel("Choose Collection");
String[] ccString = {"All", "Mostly", "Some", "Few"};
JComboBox ccComboBox = new JComboBox(ccString);
JLabel searchUsing = new JLabel("Search Using");
String[] suString = {"Title", "Artist", "Arthor", "Type"};
JComboBox suComboBox = new JComboBox(suString);
//Adding all the text and dropdown menus to the panel
c.gridx = 0;
c.gridy = 24;
panel.add(chooseCollection, c);
c.gridx = 0;
c.gridy = 25;
panel.add(ccComboBox, c);
c.gridx = 1;
c.gridy = 25;
panel.add(searchUsing, c);
c.gridx = 0;
c.gridy = 27;
panel.add(suComboBox, c);
c.gridx = 1;
c.gridy = 27;
//Setting up the text inputbox
JLabel keyword = new JLabel("Keyword or phrase");
JTextField textField = new JTextField(20);
//Adding lable and text box to the panel
panel.add(keyword);
panel.add(textField);
}
}
I would not try and force the buttons into the same layout as the other components. They are independant and should be free floating evenly spaced.
The button panel should be in a panel set with flowlayout. Then this panel should be added to the frame with borderlayout at SOUTH.
The rest of the components should go into a panel with gridbaglayout and added to the frame at CENTER.
The gridbaglayout panel then should have all its components set at the coordinates listed in the picture. If the component covers more than two cells (ie combo) then set the gridWidth property to 2.
I'd do it by having an outer BorderLayout. In the CENTER would be a GroupLayout for the label/control pairs. In the PAGE_END would be a FlowLayout for the buttons.
This uses a TitledBorder instead of the JLabel to show LIBSYS Search. If it really needs a label, put it in the PAGE_START of the border layout.
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
import javax.swing.border.*;
public class LibSysSearch {
private JComponent ui = null;
LibSysSearch() {
initUI();
}
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
// Here is our control. This puts a titled border around it,
// instead of using a label in the PAGE_START
JPanel libSysSearchControl = new JPanel(new BorderLayout());
ui.add(libSysSearchControl);
JPanel actionPanel = new JPanel(
new FlowLayout(FlowLayout.CENTER, 15, 15));
libSysSearchControl.add(actionPanel, BorderLayout.PAGE_END);
String[] actionNames = {"Search", "Reset", "Cancel"};
for (String name : actionNames) {
actionPanel.add(new JButton(name));
}
// Use GroupLayout for the label/cotrnl combos.
// make the arrays for the factory method
String[] labels = {
"Choose Collection", "Search Using",
"Keyword or phrase", "Adjacent words"
};
String[] ccString = {"All", "Mostly", "Some", "Few"};
String[] suString = {"Title", "Artist", "Arthor", "Type"};
JPanel confirmAdjacent = new JPanel(new FlowLayout(FlowLayout.LEADING,5,0));
confirmAdjacent.add(new JRadioButton("Yes", true));
confirmAdjacent.add(new JRadioButton("No"));
JComponent[] controls = {
new JComboBox(ccString),
new JTextField(20),
new JComboBox(suString),
confirmAdjacent
};
libSysSearchControl.add(getTwoColumnLayout(labels, controls));
// throw in a few borders for white space
Border border = new CompoundBorder(
new EmptyBorder(10, 10, 10, 10),
new TitledBorder("LIBSYS Search"));
border = new CompoundBorder(
border,
new EmptyBorder(10, 10, 10, 10));
libSysSearchControl.setBorder(border);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
LibSysSearch o = new LibSysSearch();
JFrame f = new JFrame("Library System Search");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
/**
* Provides a JPanel with two columns (labels & fields) laid out using
* GroupLayout. The arrays must be of equal size.
*
* Typical fields would be single line textual/input components such as
* JTextField, JPasswordField, JFormattedTextField, JSpinner, JComboBox,
* JCheckBox.. & the multi-line components wrapped in a JScrollPane -
* JTextArea or (at a stretch) JList or JTable.
*
* #param labels The first column contains labels.
* #param fields The last column contains fields.
* #param addMnemonics Add mnemonic by next available letter in label text.
* #return JComponent A JPanel with two columns of the components provided.
*/
public static JComponent getTwoColumnLayout(
JLabel[] labels,
JComponent[] fields,
boolean addMnemonics) {
if (labels.length != fields.length) {
String s = labels.length + " labels supplied for "
+ fields.length + " fields!";
throw new IllegalArgumentException(s);
}
JComponent panel = new JPanel();
GroupLayout layout = new GroupLayout(panel);
panel.setLayout(layout);
// Turn on automatically adding gaps between components
layout.setAutoCreateGaps(true);
// Create a sequential group for the horizontal axis.
GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
GroupLayout.Group yLabelGroup = layout.createParallelGroup(GroupLayout.Alignment.TRAILING);
hGroup.addGroup(yLabelGroup);
GroupLayout.Group yFieldGroup = layout.createParallelGroup();
hGroup.addGroup(yFieldGroup);
layout.setHorizontalGroup(hGroup);
// Create a sequential group for the vertical axis.
GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
layout.setVerticalGroup(vGroup);
int p = GroupLayout.PREFERRED_SIZE;
// add the components to the groups
for (JLabel label : labels) {
yLabelGroup.addComponent(label);
}
for (Component field : fields) {
yFieldGroup.addComponent(field, p, p, p);
}
for (int ii = 0; ii < labels.length; ii++) {
vGroup.addGroup(layout.createParallelGroup().
addComponent(labels[ii]).
addComponent(fields[ii], p, p, p));
}
if (addMnemonics) {
addMnemonics(labels, fields);
}
return panel;
}
private final static void addMnemonics(
JLabel[] labels,
JComponent[] fields) {
Map<Character, Object> m = new HashMap<Character, Object>();
for (int ii = 0; ii < labels.length; ii++) {
labels[ii].setLabelFor(fields[ii]);
String lwr = labels[ii].getText().toLowerCase();
for (int jj = 0; jj < lwr.length(); jj++) {
char ch = lwr.charAt(jj);
if (m.get(ch) == null && Character.isLetterOrDigit(ch)) {
m.put(ch, ch);
labels[ii].setDisplayedMnemonic(ch);
break;
}
}
}
}
/**
* Provides a JPanel with two columns (labels & fields) laid out using
* GroupLayout. The arrays must be of equal size.
*
* #param labelStrings Strings that will be used for labels.
* #param fields The corresponding fields.
* #return JComponent A JPanel with two columns of the components provided.
*/
public static JComponent getTwoColumnLayout(
String[] labelStrings,
JComponent[] fields) {
JLabel[] labels = new JLabel[labelStrings.length];
for (int ii = 0; ii < labels.length; ii++) {
labels[ii] = new JLabel(labelStrings[ii]);
}
return getTwoColumnLayout(labels, fields);
}
/**
* Provides a JPanel with two columns (labels & fields) laid out using
* GroupLayout. The arrays must be of equal size.
*
* #param labels The first column contains labels.
* #param fields The last column contains fields.
* #return JComponent A JPanel with two columns of the components provided.
*/
public static JComponent getTwoColumnLayout(
JLabel[] labels,
JComponent[] fields) {
return getTwoColumnLayout(labels, fields, true);
}
}
The problem is that you need to understand GridBagLayout. You need to layout your components onto a proper grid:
So you should have 5 rows and 12 columns to layout the way you described in your picture. Don't mind the padding (I tried to add that to make it more illustrative). Your first three rows should each have elements of gridwidth = 6 and the first should be at gridx = 0 and the second at gridx = 6. Then your "yes" and "no" buttons should each have gridwidth = 3 at gridx = 6 and gridx = 9, respectively. Finally your last row, the buttons, should each have gridwidth = 2 and gridx = 1, gridx = 5, and gridx = 9, respectively. Instead of using padding, I would just use gbc.anchor = GridBagConstraints.CENTER (for all of the components) so that the components are centered inside of their grid.
I would suggest using gbc.fill = GridBagConstraints.HORIZONTAL for the text field and combo boxes so that they line up "nice and pretty" but don't forget to set that back to gbc.fill = GridBagConstraints.NONE for the radio buttons and regular buttons (unless you want them to stretch as well).
I very haphazardly changed your code (which appeared to be in no logical order):
// Creating the grid to location of the parts
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.CENTER;
// Initializing the buttons
submit = new JButton("Submit");
c.insets = new Insets(10, 10, 10, 5);
c.gridx = 1;
c.gridy = 5;
c.gridwidth = 2;
panel.add(submit, c);
reset = new JButton("Reset");
c.gridx = 5;
// c.gridy = 20;
panel.add(reset, c);
cancel = new JButton("Cancel");
c.gridx = 9;
// c.gridy = 20;
panel.add(cancel, c);
// Handler constructor to do the actionlistening
Handler handler = new Handler();
submit.addActionListener(handler);
reset.addActionListener(handler);
cancel.addActionListener(handler);
// Creating the two dropdowns with the words next to them
JLabel chooseCollection = new JLabel("Choose Collection");
String[] ccString = { "All", "Mostly", "Some", "Few" };
JComboBox ccComboBox = new JComboBox(ccString);
JLabel searchUsing = new JLabel("Search Using");
String[] suString = { "Title", "Artist", "Arthor", "Type" };
JComboBox suComboBox = new JComboBox(suString);
// Adding all the text and dropdown menus to the panel
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 6;
c.anchor = GridBagConstraints.WEST;
panel.add(chooseCollection, c);
c.gridx = 6;
// c.gridy = 25;
c.fill = GridBagConstraints.HORIZONTAL;
panel.add(ccComboBox, c);
c.gridx = 0;
c.gridy = 2;
c.fill = GridBagConstraints.NONE;
panel.add(searchUsing, c);
c.gridx = 6;
// c.gridy = 27;
c.fill = GridBagConstraints.HORIZONTAL;
panel.add(suComboBox, c);
// Setting up the text inputbox
JLabel keyword = new JLabel("Keyword or phrase");
JTextField textField = new JTextField(20);
// Adding lable and text box to the panel
c.gridx = 0;
c.gridy = 1;
c.fill = GridBagConstraints.NONE;
panel.add(keyword, c);
c.gridx = 6;
panel.add(textField, c);
Which produced the following layout:
i would probably do it like this:
public class Test {
public Test() {
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel(new GridLayout(0, 1));
JPanel chooseCollectionPanel = new JPanel(new BorderLayout());
JPanel keywordPanel = new JPanel(new BorderLayout());
JPanel searchCategoryPanel = new JPanel(new BorderLayout());
// ...
mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
chooseCollectionPanel.setBorder(BorderFactory.createEmptyBorder(5, 0,
5, 0));
keywordPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
searchCategoryPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5,
0));
JLabel chooseCollectionLabel = new JLabel("Choose Collection: ");
JComboBox<String> chooseCollectionCB = new JComboBox<String>();
chooseCollectionCB.addItem("All");
chooseCollectionPanel.add(chooseCollectionLabel, BorderLayout.WEST);
chooseCollectionPanel.add(chooseCollectionCB, BorderLayout.CENTER);
JLabel chooseCollectionkeywordLabel = new JLabel("Choose Collection: ");
JTextField keywordCB = new JTextField(10);
keywordPanel.add(chooseCollectionkeywordLabel, BorderLayout.WEST);
keywordPanel.add(keywordCB, BorderLayout.CENTER);
// ...
mainPanel.add(chooseCollectionPanel);
mainPanel.add(keywordPanel);
mainPanel.add(searchCategoryPanel);
// ...
frame.add(mainPanel);
frame.setSize(400, 400);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new Test();
}
}

Spacing of cells and columns in Java Swing

My problem is that the last 2 columns of my second gridbagconstraints variable are spaced out too much. I have used one gridbagconstraint to manage the first column and the second one deals with the last 3.
Sadly, I cannot provide a screenshot due to being a new user :(
import java.awt.*;
import javax.swing.*;
public class Main_Window_Frame extends JFrame{
//The tabbed pane object is constructed
JTabbedPane TabGroup = new JTabbedPane();
//Jpanels to be added to TabGroup
JPanel panelAddEmployee = new JPanel();//This will create the first tab "Add Employee"
JPanel panelSearchEmployee = new JPanel();//This will create the second tab "Search for an Employee
JPanel panelRemoveEmployee = new JPanel();//This will create the third tab "Remove an Employee"
JPanel panelListAllEmployees = new JPanel();//This will create the fourth tab "List all Employees"
JPanel panelSysOptions = new JPanel();//This will create the fifth tab "System options"
//Construct GridBagConstraints for the objects within panelAddEmployee JPanel
GridBagConstraints c = new GridBagConstraints();
GridBagConstraints gbc = new GridBagConstraints();
//Add employee panel Label declarations
JLabel lblAddEmployee;
JLabel lblEmpID;
JLabel lblEmpIDout;
JLabel lblForename;
JLabel lblSurname;
JLabel lblGender;
JLabel lblDateBirth;
JLabel lblAddress;
JLabel lblPhoneNo;
JLabel lblEmail;
JLabel lblJobTitle;
JLabel lblSalary;
JLabel lblNatNo;
JLabel lblStartDate;
//Add employee panel TextField declarations
JTextField txtForename;
JTextField txtSurname;
JTextField txtAddress;
JTextField txtPhoneNo;
JTextField txtEmail;
JTextField txtJobTitle;
JTextField txtSalary;
JTextField txtNatNo;
//Add employee panel RadioButton declarations
JRadioButton radMale;
JRadioButton radFemale;
//Add employee panel ComboBox declarations
JComboBox cbDob1;
JComboBox cbDob2;
JComboBox cbDob3;
JComboBox cbDateStart1;
JComboBox cbDateStart2;
JComboBox cbDateStart3;
//Add employee panel label array
JLabel[] addEmployeeLabels = new JLabel[13];
//Add employee panel textField array
JTextField[] addEmployeeTextFields = new JTextField[8];
protected String[] DDBirthDate = {"01","02","03","04","05","06","07",
"08","09","10","11","12",
"13","14","15","16","17","18","19",
"20","21","22","23","24","25","26",
"27","28","29","30","31"};
protected String[] MMBirthDate = {"01","02","03","04","05","06","07",
"08","09","10","11","12"};
protected String[] YYYYBirthDate = {"1996","1995","1994","1993","1992",
"1991","1990","1989","1988","1987",
"1986","1985","1984","1983","1982",
"1981","1980 "," 1979 ","1978","1977",
"1976","1975","1974","1973","1972","1971",
"1970","1969","1968","1967 ","1966",
"1965","1964","1963","1962","1961","1960",
"1959","1958","1957","1956","1955",
"1954","1953","1952","1951","1950",
"1949","1948","1947","1946","1945",
"1944","1943","1942","1941"};
protected String[] YYYYStartDate = {"2012","2011","2010"};
public Main_Window_Frame() {
super("Employee Record System");
setSize(750,500); //set the size of the form
//This creates the template for the multiple tabs using JTabbedPane
getContentPane().add(TabGroup);
//Add the GridBagLayout manager to the panelAddEmployee JPanel
panelAddEmployee.setLayout(new GridBagLayout());
//Add the GridBagLayout manager to the panelAddEmployee JPanel
panelSearchEmployee.setLayout(new GridBagLayout());
generateEmployeeAttributeLabels();
addEmployeePanelObjects();
addListAllEmployeesPanelObjects();
addSystemOptionsPanelObjects();
//This adds the first, second, third and final tab to the tabbedPanel Object
TabGroup.addTab("Add Employee", panelAddEmployee);
TabGroup.addTab("Search for an Employee", panelSearchEmployee);
TabGroup.addTab("Remove an Employee", panelRemoveEmployee);
TabGroup.addTab("List all Employees", panelListAllEmployees);
TabGroup.addTab("System Options", panelSysOptions);
}
public void generateEmployeeAttributeLabels(){
//Labels are assigned to a label array
addEmployeeLabels[0] = lblAddEmployee = new JLabel(); lblAddEmployee.setText("Add Employee"); //Set the text to "Add Employee"
addEmployeeLabels[1] = lblEmpID = new JLabel(); lblEmpID.setText("Employee ID:");
addEmployeeLabels[2] = lblForename = new JLabel(); lblForename.setText("Forename:");
addEmployeeLabels[3] = lblSurname = new JLabel(); lblSurname.setText("Surname:");
addEmployeeLabels[4] = lblGender = new JLabel(); lblGender.setText("Gender:");
addEmployeeLabels[5] = lblDateBirth = new JLabel(); lblDateBirth.setText("Date of Birth:");
addEmployeeLabels[6] = lblAddress = new JLabel(); lblAddress.setText("Address:");
addEmployeeLabels[7] = lblPhoneNo = new JLabel(); lblPhoneNo.setText("Phone Number:");
addEmployeeLabels[8] = lblEmail = new JLabel(); lblEmail.setText("Email Address:");
addEmployeeLabels[9] = lblJobTitle = new JLabel(); lblJobTitle.setText("Job Title:");
addEmployeeLabels[10] = lblSalary = new JLabel(); lblSalary.setText("Salary:");
addEmployeeLabels[11] = lblNatNo = new JLabel(); lblNatNo.setText("National Insurance no:");
addEmployeeLabels[12] = lblStartDate = new JLabel(); lblStartDate.setText("Start Date:");
//GridBagConstraints for the title label "Add Employee"
c.fill = GridBagConstraints.HORIZONTAL;
int j = 0;
//This for loop adds all of the labels to the add employee panel.
//More efficient than multiple lines of code for each label.
for(int i = 0; i < 13; i++){
//If the element is the "Add Employee" label then we give it the appropriate sizes
if(i == 0){
c.insets = new Insets(0,0,0,0); //Insets are 0, assigned to upper-most top left
c.weightx = 0.5; //horizontal weight is 0.5
c.gridx = 0; //Place in column 0
c.gridy = 0; //Place in row 0
addEmployeeLabels[0].setFont(new Font("Arial",Font.BOLD,24));
}else{
//If the element is the "Start Date" Label then
if (i == 12){
c.weighty = 1.0; //vertical weight is 0.5
c.anchor = GridBagConstraints.PAGE_START; //Ensures last label is at the edge of its display area
c.gridx = 0; //Place in column 0
c.gridy = 12; //Place in column 12
addEmployeeLabels[12].setFont(new Font("Arial",Font.PLAIN,12));
//For every other label, a default size and relational location is assigned.
}else{
c.insets = new Insets(15,5,0,0);
c.weightx = 0.5;
c.gridx = 0; //Place in column 0
c.gridy = i; //Place in column i (relational positioning based on element index value)
addEmployeeLabels[i].setFont(new Font("Arial",Font.PLAIN,12));
}
}
//Adds each label in the array to the "panelAddEmployee" Panel
panelAddEmployee.add(addEmployeeLabels[i], c);
//Adds each label in the array to the "panelAddEmployee" Panel
//panelSearchEmployee.add(addEmployeeLabels[i], c);
}
}
public void addEmployeePanelObjects(){
gbc.gridwidth = 1;
//Construct lblEmpIDout label
lblEmpIDout = new JLabel();
lblEmpIDout.setText("0");
//Construct radMale radio button
radMale = new JRadioButton();
radMale.setText("Male?");
//Construct radFemale radio button
radFemale = new JRadioButton();
radFemale.setText("Female?");
cbDob1 = new JComboBox();
cbDateStart1 = new JComboBox();
for(int i = 0; i < DDBirthDate.length; i++){
cbDob1.addItem(DDBirthDate[i]);
cbDateStart1.addItem(DDBirthDate[i]);
}
cbDob2 = new JComboBox();
cbDateStart2 = new JComboBox();
for(int i = 0; i < MMBirthDate.length; i++){
cbDob2.addItem(MMBirthDate[i]);
cbDateStart2.addItem(MMBirthDate[i]);
}
cbDob3 = new JComboBox();
cbDateStart3 = new JComboBox();
for(int i = 0; i < YYYYBirthDate.length; i++){
cbDob3.addItem(YYYYBirthDate[i]);
cbDateStart3.addItem(YYYYBirthDate[i]);
}
//TextFields are assigned to a TextField array
addEmployeeTextFields[0] = txtForename = new JTextField();
addEmployeeTextFields[1] = txtSurname = new JTextField();
addEmployeeTextFields[2] = txtAddress = new JTextField();
addEmployeeTextFields[3] = txtPhoneNo = new JTextField();
addEmployeeTextFields[4] = txtEmail = new JTextField();
addEmployeeTextFields[5] = txtJobTitle = new JTextField();
addEmployeeTextFields[6] = txtSalary = new JTextField();
addEmployeeTextFields[7] = txtNatNo = new JTextField();
int j = 0;
//This for loop adds all of the labels to the add employee panel.
//More efficient than multiple lines of code for each label.
for(int i = 0; i < 13; i++){
gbc.insets = new Insets(15,5,0,0);
gbc.gridy = i;
gbc.gridx = 0;
gbc.weightx = 1;
gbc.weighty = 1;
if (i == 0 || i == 1 ||i == 4 || i == 5 || i == 12 ){
if(i==1){
panelAddEmployee.add(lblEmpIDout, gbc);
}
if(i==4){
panelAddEmployee.add(radMale,gbc);
gbc.gridx = 1;
panelAddEmployee.add(radFemale,gbc);
gbc.gridx = 0;
}
if(i==5){
panelAddEmployee.add(cbDob1,gbc);
gbc.gridx = 1;
panelAddEmployee.add(cbDob2,gbc);
gbc.gridx = 2;
panelAddEmployee.add(cbDob3,gbc);
gbc.gridx = 0;
}
if(i==12){
panelAddEmployee.add(cbDateStart1,gbc);
gbc.gridx = 1;
panelAddEmployee.add(cbDateStart2,gbc);
gbc.gridx = 2;
panelAddEmployee.add(cbDateStart3,gbc);
gbc.gridx = 0;
}
//Do not add a text box to title, ID
//gender, date of birth or start date
}else{
//Adds each textfield in the array to the "panelAddEmployee" Panel
panelAddEmployee.add(addEmployeeTextFields[j], gbc);
j++;
}
}
}
public void addSearchEmployeePanelObjects(){
}
public void addListAllEmployeesPanelObjects(){
}
public void addSystemOptionsPanelObjects(){
}
}
Screenshot

Categories