I'm trying to create panel with a GridLayout(7,2)
membersPanel = new JPanel(new GridLayout(7,2));
However, when I add the components (Labels, Combobox, textfields, etc) the components show up in 3 columns, like this:
I've tryed changing the number of columns to 1 or even 0, but the panel stays the same.
What can I do?
EDIT:
Here's more code:
p1 = new JPanel();
membersPanel = new JPanel(new GridLayout(7,0));
resourcesLabel = new JLabel("Resources");
membersPanel.add(resourcesLabel);
emptyLabel5 = new JLabel("");
membersPanel.add(emptyLabel5);
emptyLabel6 = new JLabel("");
membersPanel.add(emptyLabel6);
comboBoxResource = new JComboBox(configs.XMLreaderDOM4J.readResourceID());
membersPanel.add(comboBoxResource);
slider1 = new SliderWithTextField(1,10);
textSli1 = new TextFieldFromSlider(this, slider1);
slider1.setTextField(textSli1);
slider1.setValue(1);
membersPanel.add(slider1);
membersPanel.add(textSli1);
emptyLabel2 = new JLabel();
membersPanel.add(emptyLabel2);
addButton1 = new JButton("Add");
addButton1.addActionListener(new TrataEvento());
membersPanel.add(addButton1);
agregator1Label = new JLabel("Agretagor1");
membersPanel.add(agregator1Label);
comboBoxAgregator1 = new JComboBox(configs.XMLreaderDOM4J.readAgregator1ID());
membersPanel.add(comboBoxAgregator1);
slider2 = new SliderWithTextField(1,10);
textSli2 = new TextFieldFromSlider(this, slider2);
slider2.setTextField(textSli2);
slider2.setValue(1);
membersPanel.add(slider2);
membersPanel.add(textSli2);
addButton2 = new JButton("Add");
addButton2.addActionListener(new TrataEvento());
membersPanel.add(addButton2);
emptyLabel3 = new JLabel();
membersPanel.add(emptyLabel3);
agregator0Label = new JLabel("Agregator0");
membersPanel.add(agregator0Label);
comboBoxAgregator0 = new JComboBox(configs.XMLreaderDOM4J.readAgregator0ID());
membersPanel.add(comboBoxAgregator0);
slider3 = new SliderWithTextField(1,10);
textSli3 = new TextFieldFromSlider(this, slider3);
slider3.setTextField(textSli3);
slider3.setValue(1);
membersPanel.add(slider3);
membersPanel.add(textSli3);
addButton3 = new JButton("Add");
addButton3.addActionListener(new TrataEvento());
membersPanel.add(addButton3);
emptyLabel4 = new JLabel();
membersPanel.add(emptyLabel4);
p1.add(membersPanel);
Swing adjusts the number of columns used for GridLayout if the number of components added exceeds the original number specified. Use 0 to specify an adjustable number of rows:
membersPanel = new JPanel(new GridLayout(0, 2));
This will make any future refactoring easier.
number of JComponent layerd by GridLayout(7,2) don't corresponding with JComponents into one container,
there must be layed more than 21 JComponents into one container
output from super(new GridLayout(8, 8));
output from super(new GridLayout(N, N));
from code
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.EventHandler;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/** based on #see http://stackoverflow.com/questions/7702697 */
public class GridButtonPanel extends JPanel {
private static final int N = 4;
private final List<GridButton> list = new ArrayList<GridButton>();
public GridButtonPanel() {
//super(new GridLayout(8, 8));
super(new GridLayout(N, N));
for (int i = 0; i < N * N; i++) {
int row = i / N;
int col = i % N;
GridButton gb = new GridButton(row, col);
gb.addActionListener((ActionListener) EventHandler.create(ActionListener.class, this,
"actionName" + row + "A" + col));
list.add(gb);
this.add(gb);
}
}
public void actionName0A0() {
System.out.println(" Grid at Row 0, Column 0 ");
}
public void actionName0A1() {
System.out.println(" Grid at Row 0, Column 1 ");
}
public void actionName1A0() {
System.out.println(" Grid at Row 1, Column 0 ");
}
public void actionName1A1() {
System.out.println(" Grid at Row 1, Column 1 ");
}
private GridButton getGridButton(int r, int c) {
int index = r * N + c;
return list.get(index);
}
private class GridButton extends JButton {
private int row;
private int col;
public GridButton(int row, int col) {
super("Row - " + row + ", Col - " + col);
this.row = row;
this.col = col;
this.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int r = GridButton.this.row;
int c = GridButton.this.col;
GridButton gb = GridButtonPanel.this.getGridButton(r, c);
System.out.println("r" + r + ",c" + c
+ " " + (GridButton.this == gb)
+ " " + (GridButton.this.equals(gb)));
}
});
}
}
private void display() {
JFrame f = new JFrame("GridButton");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new GridButtonPanel().display();
}
});
}
}
Related
I have a matrix of colorful buttons and I need to compare their colors and their values after clicking them. All my code does is removing every button without searching their values or colors.Also i need to add the jlabel without rearranging jbuttons. How can i fix the problem?
public class Legos2 extends JFrame implements ActionListener{
private static final long serialVersionUID = 1L;
public JPanel jp = (JPanel)this.getContentPane();
public JButton[][] jb = new JButton[12][24];//my matrix
public static JLabel jl = new JLabel("score",SwingConstants.CENTER);//a jlabel to count the scores every time two buttons are removed
public Legos2() {
super();
this.setSize(2000,2000);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
jp.setLayout(new GridLayout(12, 24));//size of my jpanel
Random rnd = new Random();
Color[] c = {Color.lightGray, Color.gray, Color.white, Color.cyan};//colored jbuttons
final int MAXCOLOR = c.length;
JButton jb1;
for(int i = 0;i <jb.length;i++) {
for(int j = 0; j<jb[i].length; j++) {
int k = (int) (Math.random()*9+1);//k is a random integer from 1 to 9
jb1 = new JButton(Integer.toString(k));
add(jb1);
jb[i][j]=jb1;
jb[i][j].addActionListener(this);
}
}
for(int i=0; i<jb.length; i++){
for(int j = 0; j<jb[i].length; j++) {
jb[i][j].setBackground(c[rnd.nextInt(MAXCOLOR)]);//i add colors in here
}
}
for (int row = 0; row < jb.length; row++) {
for (int column = 0; column < jb[row].length; column++) {
jb[row][column].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
String buttonText = button.getText();
// now iterate over all the jbuttons you have
for(int i=0;i<jb.length;i++){
for(int j=0;j<jb[0].length;j++){
JButton b = jb[i][j];
String bText = b.getText();
if(e.getSource()==b)
if(buttonText.equals(bText)){
b.setEnabled(false);
jl.setText(Integer.toString(i));
}
}
}
}
}
);
jp.add(jb[row][column]);
}
}
}
}
The following is mcve of the required functionality. Please review and ask for clarifications as needed:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class Legos2 extends JFrame{
private static final long serialVersionUID = 1L;
private static final int ROWS = 12, COLS =24;
public JButton[][] jb = new JButton[ROWS][COLS];
private int score = 0;
public static JLabel jl;
public Legos2() {
super();
this.setSize(2000,2000);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel jp= new JPanel();
jp.setLayout(new GridLayout(ROWS, COLS));
Random rnd = new Random();
Color[] c = {Color.lightGray, Color.gray, Color.white, Color.cyan};
final int MAXCOLOR = c.length;
//all can be done in one loop
for(int i = 0;i <jb.length;i++) {
for(int j = 0; j<jb[i].length; j++) {
int k = (int) (Math.random()*9+1);//k is a random integer from 1 to 9
JButton button = new JButton(Integer.toString(k));
button.setBackground(c[rnd.nextInt(MAXCOLOR)]);
button.addActionListener(e -> {
disableTwoMatchingButtons(button);
});
jb[i][j]=button;
jp.add(button);
}
}
add(jp); //add panel at content pane center
jl= new JLabel("",SwingConstants.CENTER);
updateScore(0);
add(jl, BorderLayout.PAGE_END); //add label at content pane bottom
pack();
setVisible(true);
}
private void disableTwoMatchingButtons(JButton button) {
for(int i=0;i<jb.length;i++){
for(int j=0;j<jb[0].length;j++){
JButton b = jb[i][j];
if(b.isEnabled() && button.getText().equals(b.getText()) &&
button.getBackground().equals(b.getBackground())){
b.setEnabled(false);
button.setEnabled(false);
updateScore(2* Integer.valueOf(b.getText()));
return;
}
}
}
}
private void updateScore(int value) {
score += value;
jl.setText("Score: "+ score );
}
public static void main(String[] args) {
new Legos2();
}
}
If you need to disable all matching button, and not just two, use :
private void disableAllMatchingButtons(JButton button) {
for(int i=0;i<jb.length;i++){
for(int j=0;j<jb[0].length;j++){
JButton b = jb[i][j];
if(b.isEnabled() && button.getText().equals(b.getText())
&& button.getBackground().equals(b.getBackground())){
b.setEnabled(false);
updateScore(Integer.valueOf(b.getText()));
}
}
}
}
(instead of disableTwoMatchingButtons)
For future post always consider posting an mcve, and stick to one question per post.
I need to make a piece of text that scrolls along the page by taking each letter and moving it from one jlabel to the next. This is my code so far. It needs a delay because its too fast but it seem to crash when the string has finished. Any help would be appreciated?.
package Lab4;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
public class Scroll extends JFrame implements ActionListener {
final int scrollNumber = 10;
JTextField inputTextField = new JTextField(10);
JLabel[] output = new JLabel[scrollNumber];
JLabel text = new JLabel("Enter text and press Return",
SwingConstants.CENTER);
public Scroll() {
setLayout(new GridLayout(2, 1));
JPanel row1 = new JPanel(new GridLayout(1, 10));
output[0] = new JLabel();
output[1] = new JLabel();
output[2] = new JLabel();
output[3] = new JLabel();
output[4] = new JLabel();
output[5] = new JLabel();
output[6] = new JLabel();
output[7] = new JLabel();
output[8] = new JLabel();
output[9] = new JLabel();
row1.add(output[9]);
row1.add(output[8]);
row1.add(output[7]);
row1.add(output[6]);
row1.add(output[5]);
row1.add(output[4]);
row1.add(output[3]);
row1.add(output[2]);
row1.add(output[1]);
row1.add(output[0]);
add(row1);
JPanel row2 = new JPanel(new GridLayout(1, 2));
row2.add(text);
row2.add(inputTextField);
add(row2);
inputTextField.addActionListener(this);
}
public void shift() {
output[9].setText(output[8].getText());
output[8].setText(output[7].getText());
output[7].setText(output[6].getText());
output[6].setText(output[5].getText());
output[5].setText(output[4].getText());
output[4].setText(output[3].getText());
output[3].setText(output[2].getText());
output[2].setText(output[1].getText());
output[1].setText(output[0].getText());
}
public void run(String input) {
int length = input.length();
int i = 0;
while (true) {
if (output[0] != null) {
output[0].setText(input.substring(i, i + 1));
} else {
output[0].setText("");
}
i = i + 1;
System.out.println("0" + output[0].getText());
System.out.println("1" + output[1].getText());
System.out.println("2" + output[2].getText());
System.out.println("3" + output[3].getText());
System.out.println("4" + output[4].getText());
System.out.println("5" + output[5].getText());
System.out.println("6" + output[6].getText());
System.out.println("7" + output[7].getText());
System.out.println("8" + output[8].getText());
System.out.println("9" + output[9].getText());
shift();
}
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == inputTextField) {
String j = inputTextField.getText();
run("abcdef");
System.out.println(j);
}
}
}
So first of all. Yes your application crashes. Technically its an IndexOutOfBoundsException that you get when invoking input.substring(i, i + 1) in your run method. You increment i in an infinite loop without resitriction. And so it gets higher than your string length with the result that substring then throws that exception.
So first fix is a restriction when incrementing your index.
[...]
i = i + 1;
if(i > length - 1)
i = 0;
Next fix should be a delay. But thats not as easy as it sounds. You should start learning how Threads work in Java because you will need to start one. Thats because you should never send your main Thread to sleep or your GUI will get unresponsible. So I will give you one simple solution and remind you to learn how Threads work.
So remove your run method and change your actionPerformed method like this:
public void actionPerformed(ActionEvent e) {
if (e.getSource() == inputTextField) {
String j = inputTextField.getText();
// run("abcdef");
new Thread(new Runnable(){
#Override
public void run() {
int length = j.length();
int i = 0;
while (true) {
if (output[0] != null) {
output[0].setText(j.substring(i, i + 1));
} else {
output[0].setText("");
}
i = i + 1;
if(i > length - 1)
i = 0;
try {
Thread.sleep(500); // your delay in ms
} catch (InterruptedException e) {
e.printStackTrace();
}
shift();
}
}
}).start();
}
}
I am trying to make a sign in program with a time clock display. I am having a hard time trying to get the clock into the already made JPanel. It currently pops up 2 seperate JPanels when I run the program. Please help with any suggestions.
CODE:
private static JLabel lblUserName;
private static JTextField txtUserName;
private static JButton btnSignIn;
private static JLabel lblPassword;
private static JPasswordField txtPassword;
private static JButton btnCancel;
private static JTabbedPane tabbedPane;
public static void main(String[] args)
{
UserSignIn frame = new UserSignIn();
JFrame frm = new JFrame();
SimpleDigitalClock clock1 = new SimpleDigitalClock();
frm.add(clock1);
//Pack
frm.pack();
frame.pack();
// Set origional focus on User Name text field
txtUserName.requestFocusInWindow();
// Make Visible
frame.setVisible(true);
frm.setVisible(true);
}
static class SimpleDigitalClock extends JPanel
{
String stringTime;
int hour, minute, second;
String aHour = "";
String bMinute = "";
String cSecond = "";
public void setStringTime(String abc)
{
this.stringTime = abc;
}
public int Number(int a, int b)
{
return (a <= b) ? a : b;
}
SimpleDigitalClock()
{
Timer t = new Timer(1000, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
repaint();
}
});
t.start();
}
#Override
public void paintComponent(Graphics v)
{
super.paintComponent(v);
Calendar rite = Calendar.getInstance();
hour = rite.get(Calendar.HOUR_OF_DAY);
minute = rite.get(Calendar.MINUTE);
second = rite.get(Calendar.SECOND);
if (hour < 10)
{
this.aHour = "0";
}
if (hour >= 10)
{
this.aHour = "";
}
if (minute < 10)
{
this.bMinute = "0";
}
if (minute >= 10)
{
this.bMinute = "";
}
if (second < 10)
{
this.cSecond = "0";
}
if (second >= 10)
{
this.cSecond = "";
}
setStringTime(aHour + hour + ":" + bMinute+ minute + ":" + cSecond + second);
v.setColor(Color.RED);
int length = Number(this.getWidth(),this.getHeight());
Font Font1 = new Font("Digital", Font.BOLD, length / 5);
v.setFont(Font1);
v.drawString(stringTime, (int) length/6, length/2);
}
#Override
public Dimension getPreferredSize()
{
return new Dimension(200, 200);
}
}
public UserSignIn()
{
initGUI();
}
public void initGUI()
{
setTitle("Login");
JPanel pnlUserSignIn = new JPanel(new GridBagLayout());
this.getContentPane().add(pnlUserSignIn);
//build table for employees signed in
JTable t = new JTable(null);
JLabel label = new JLabel("Employees Currently Signed In");
// ROW 1 BUTTONS
// Username and Sign In buttons
lblUserName = new JLabel("Username: ");
txtUserName = new JTextField("Username");
// Actions
//txtUserName.addMouseListener(this);
// Adding objects to Panel
JPanel pnlLogin = new JPanel();
pnlLogin.add(lblUserName);
pnlLogin.add(txtUserName);
//ROW 2 BUTTONS
//Password and Cancel
btnSignIn = new JButton("Sign In");
btnCancel=new JButton("Cancel");
//Actions
btnSignIn.addActionListener(this);
btnCancel.addActionListener(this);
// Adding objects to Panel
JPanel pnlPassword = new JPanel();
pnlPassword.add(btnSignIn);
pnlPassword.add(btnCancel);
JPanel detailsPanel = new JPanel();
detailsPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
GridBagConstraints gbc = new GridBagConstraints();
// Putting Objects into the grid
gbc.gridx = 0;
gbc.gridy = 0;
pnlUserSignIn.add(label, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
pnlUserSignIn.add(new JScrollPane(t), gbc);
gbc.gridx = 0;
gbc.gridy = 2;
pnlUserSignIn.add(pnlLogin, gbc);
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 2;
pnlUserSignIn.add(pnlPassword, gbc);
//gbc.gridx = 1;
//gbc.gridy = 1;
//gbc.gridwidth = 1;
//gbc.gridheight = 2;
//panel.add(detailsPanel, gbc);
this.pack();
this.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent actionEvent)
{
if(actionEvent.getSource()==btnCancel)
{
System.exit(0);
}
//if(actionEvent.getSource()==txtUserName)
//{
// txtUserName.setText("");
// txtUserName.requestFocus();
//}
}
PLEASE IGNORE THE COMMENTED CODE, I am working on many things at once.
You don't need another frame. Just add clock to existing one. For example to the SOUTH:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.Timer;
public class UserSignIn extends JFrame implements ActionListener{
private static JLabel lblUserName;
private static JTextField txtUserName;
private static JButton btnSignIn;
private static JLabel lblPassword;
private static JPasswordField txtPassword;
private static JButton btnCancel;
private static JTabbedPane tabbedPane;
public static void main(String[] args) {
UserSignIn frame = new UserSignIn();
SimpleDigitalClock clock1 = new SimpleDigitalClock();
frame.add(clock1, BorderLayout.SOUTH);
// Pack
frame.pack();
// Set origional focus on User Name text field
txtUserName.requestFocusInWindow();
// Make Visible
frame.setVisible(true);
}
static class SimpleDigitalClock extends JPanel {
String stringTime;
int hour, minute, second;
String aHour = "";
String bMinute = "";
String cSecond = "";
public void setStringTime(String abc) {
this.stringTime = abc;
}
public int Number(int a, int b) {
return (a <= b) ? a : b;
}
SimpleDigitalClock() {
Timer t = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
repaint();
}
});
t.start();
}
#Override
public void paintComponent(Graphics v) {
super.paintComponent(v);
Calendar rite = Calendar.getInstance();
hour = rite.get(Calendar.HOUR_OF_DAY);
minute = rite.get(Calendar.MINUTE);
second = rite.get(Calendar.SECOND);
if (hour < 10) {
this.aHour = "0";
}
if (hour >= 10) {
this.aHour = "";
}
if (minute < 10) {
this.bMinute = "0";
}
if (minute >= 10) {
this.bMinute = "";
}
if (second < 10) {
this.cSecond = "0";
}
if (second >= 10) {
this.cSecond = "";
}
setStringTime(aHour + hour + ":" + bMinute + minute + ":" + cSecond
+ second);
v.setColor(Color.RED);
int length = Number(this.getWidth(), this.getHeight());
Font Font1 = new Font("Digital", Font.BOLD, length / 5);
v.setFont(Font1);
v.drawString(stringTime, (int) length / 6, length / 2);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public UserSignIn() {
initGUI();
}
public void initGUI() {
setTitle("Login");
JPanel pnlUserSignIn = new JPanel(new GridBagLayout());
this.getContentPane().add(pnlUserSignIn);
// build table for employees signed in
JTable t = new JTable(null);
JLabel label = new JLabel("Employees Currently Signed In");
// ROW 1 BUTTONS
// Username and Sign In buttons
lblUserName = new JLabel("Username: ");
txtUserName = new JTextField("Username");
// Actions
// txtUserName.addMouseListener(this);
// Adding objects to Panel
JPanel pnlLogin = new JPanel();
pnlLogin.add(lblUserName);
pnlLogin.add(txtUserName);
// ROW 2 BUTTONS
// Password and Cancel
btnSignIn = new JButton("Sign In");
btnCancel = new JButton("Cancel");
// Actions
btnSignIn.addActionListener(this);
btnCancel.addActionListener(this);
// Adding objects to Panel
JPanel pnlPassword = new JPanel();
pnlPassword.add(btnSignIn);
pnlPassword.add(btnCancel);
JPanel detailsPanel = new JPanel();
detailsPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
GridBagConstraints gbc = new GridBagConstraints();
// Putting Objects into the grid
gbc.gridx = 0;
gbc.gridy = 0;
pnlUserSignIn.add(label, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
pnlUserSignIn.add(new JScrollPane(t), gbc);
gbc.gridx = 0;
gbc.gridy = 2;
pnlUserSignIn.add(pnlLogin, gbc);
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 2;
pnlUserSignIn.add(pnlPassword, gbc);
// gbc.gridx = 1;
// gbc.gridy = 1;
// gbc.gridwidth = 1;
// gbc.gridheight = 2;
// panel.add(detailsPanel, gbc);
this.pack();
this.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == btnCancel) {
System.exit(0);
}
// if(actionEvent.getSource()==txtUserName)
// {
// txtUserName.setText("");
// txtUserName.requestFocus();
// }
}
}
I am creating a simple program, which will allow me to add single character to JTextField by pressing JButton. In this program, I have an array of string named words & I have a String name word, which is allowing me to choose words randomly from the array of words. I am using a for loop to draw the JTextFields. Number of the JTextField depends on the length of the word
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.Random;
public class secondTab extends JFrame
{
JTabbedPane Pane = new JTabbedPane();
JPanel second = new JPanel();
JButton guess1 = new JButton();
Random r = new Random();
JTextField Text[] = new JTextField[10];
JButton A = new JButton();
String words[] = {"JAVA" , "FLOAT" , "MAIN" , "STATIC", "FINAL", "PRIVATE" , "CHAR", "BOOLEAN" , "CASE"}; // An array to put the words
String word = words[r.nextInt(words.length)];
int i;
public static void main(String args[])
{
//construct frame
new secondTab().show();
}
public secondTab()
{
// code to build the form
setTitle("Adding Character");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new GridBagLayout());
// position tabbed pane
GridBagConstraints gridConstraints = new GridBagConstraints();
gridConstraints.gridx = 1;
gridConstraints.gridy = 1;
Pane.setForeground(Color.YELLOW);
Pane.setBackground(Color.MAGENTA);
getContentPane().add(Pane, gridConstraints);
getContentPane().setLayout(new GridBagLayout());
second.setLayout(new GridBagLayout());
guess1.setText("New Word");
gridConstraints.gridx = 0;
gridConstraints.gridy = 0;
second.add(guess1, gridConstraints);
for( i = 1; i <=word.length(); i++)
{
Text[i] = new JTextField();
Text[i].setPreferredSize(new Dimension(80, 80));
gridConstraints.gridx = 0;
gridConstraints.gridy = 2;
second.add(Text[i]);
}
A.setText("A");
A.setPreferredSize(new Dimension(80, 80));
gridConstraints.gridx = 0;
gridConstraints.gridy = 2;
A.setHorizontalAlignment(SwingConstants.CENTER);
second.add(A, gridConstraints);
I have a JButton named A, this JButton is having some error. I have the string named choice, it contains only one character "Ä". So, I added some method in my Jbutton, Which compare the string choice to the word ( the word which is randomly selected above). Whenever it find "A" in the word, it must have to draw that "A" in the Jtextfield to the specific location but its not drawing...
A.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String choice = "A";
if (i < word.length() & i < choice.length())
{
if (word.charAt(i) == choice.charAt(i))
{
Text[i].setText(choice.charAt(i) + " ");
}
}
}
});
// Action Performed method for the JButton guess1
guess1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
dispose();
new secondTab().show();
}
});
Pane.addTab("Game ", second);
pack();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setBounds((int) (0.5 * (screenSize.width - getWidth())), (int) (0.5 *
(screenSize.height - getHeight())), getWidth(), getHeight());
}
}
Please check that video http://www.youtube.com/watch?v=Tx5QsET9IWs starting from 0.41 second . I wanna do the same thing...
Thanks....
The problem is the use of the i variable
It is first used to construct the fields
for( i = 1; i <=word.length(); i++)
{
Text[i] = new JTextField();
Text[i].setPreferredSize(new Dimension(80, 80));
gridConstraints.gridx = 0;
gridConstraints.gridy = 2;
second.add(Text[i]);
}
This now means that i is now equal to word.length()
You then re-use the variable (as is)...
public void actionPerformed(ActionEvent e)
{
String choice = "A";
if (i < word.length() & i < choice.length())
{
if (word.charAt(i) == choice.charAt(i))
{
Text[i].setText(choice.charAt(i) + " ");
}
}
}
Which won't work. i equals word.length(), meaning it will never enter the first level of the if statement.
Make i local and use it only to build the field array.
In the actionPerformed method, you simply need to be checking all the occurrences of A within the word and set the appropriate text field
Updated with working example...
There are a number of tricks for trying to find the index of all the occurrences of character in the String.
The simplest would be to simply loop through the length of the String and use String#charAt and compare that with the value you are trying to match...
for (int index = 0; index < word.length(); index++) {
if (Character.toLowerCase(word.charAt(index)) == Character.toLowerCase(choice)) {
Text[index].setText(Character.toString(choice));
}
}
I use a slightly more complicated, but flexible approach, using regular expression to find all the occurrence of a given pattern...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.AbstractAction;
import static javax.swing.Action.NAME;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class WordGuess {
public static void main(String[] args) {
new WordGuess();
}
public WordGuess() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
public static final String WORDS[] = {"JAVA", "FLOAT", "MAIN", "STATIC", "FINAL", "PRIVATE", "CHAR", "BOOLEAN", "CASE"}; // An array to put the words
private String word;
private List<JTextField> fields;
private JPanel pnlFields;
public TestPane() {
setLayout(new BorderLayout());
pnlFields = new JPanel();
add(pnlFields);
JPanel buttons = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
for (int index = 0; index < 26; index++) {
if (index % 13 == 0) {
gbc.gridx = 0;
gbc.gridy++;
}
gbc.gridx++;
JButton btn = new JButton(new LetterAction(Character.toString((char) ('A' + index))));
btn.setMargin(new Insets(0, 0, 0, 0));
buttons.add(btn, gbc);
}
add(buttons, BorderLayout.NORTH);
reset();
}
public void reset() {
word = WORDS[(int) Math.round(Math.random() * (WORDS.length - 1))];
pnlFields.removeAll();
fields = new ArrayList<>(word.length());
for (int index = 0; index < word.length(); index++) {
JTextField field = new JTextField(3);
field.setEditable(false);
field.setHorizontalAlignment(JTextField.CENTER);
pnlFields.add(field);
fields.add(field);
}
}
protected class LetterAction extends AbstractAction {
public LetterAction(String value) {
putValue(NAME, value);
}
#Override
public void actionPerformed(ActionEvent e) {
String value = getValue(NAME).toString().toLowerCase();
List<Integer[]> occurances = findAllIndicies(word.toLowerCase(), value);
System.out.println(word + " has " + occurances.size() + " occurances of " + value);
for (Integer[] index : occurances) {
fields.get(index[0]).setText(value.toUpperCase());
}
}
}
}
public static List<Integer[]> findAllIndicies(String value, String regExp) {
Pattern pattern = Pattern.compile(regExp);
return findAllIndicies(value, pattern);
}
public static List<Integer[]> findAllIndicies(String value, Pattern pattern) {
Matcher matcher = pattern.matcher(value);
String match = null;
List<Integer[]> lstMatches = new ArrayList<Integer[]>(5);
while (matcher.find()) {
int startIndex = matcher.start();
int endIndex = matcher.end();
lstMatches.add(new Integer[]{startIndex, endIndex});
}
return Collections.unmodifiableList(lstMatches);
}
}
This is an example where you press a button and jList1 is refilled with items from a1 to a1000.:
//variable
private List<String> list = new ArrayList<>();
...
//main method
jList1.setModel(new DefaultListModel());
for(int i = 0; i < 1000; i++) {
list.add("a"+i);
}
...
//button action - jList1 refill
DefaultListModel dtm = (DefaultListModel)jList1.getModel();
dtm.removeAllElements();
for(String s : list) {
dtm.addElement(s);
}
If I fill the jList1, then select (with mouse) 0 index (first element in jList) and then press the button the program freezes while refilling the list. If I select any other element or do not select any item in the list at all then it fills just fine.
P.S. This example is done without any swing or EWT threads, because the main reason was found using them.
SSCCE:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package lt;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
/**
*
* #author Minutis
*/
public class Window {
public static void main(String[] args) {
final List<String> list = new ArrayList<>();
JFrame frame = new JFrame("BorderLayout Frame");
JPanel panel = new JPanel();
final JList jList1 = new JList();
JButton refill = new JButton("Refill");
jList1.setModel(new DefaultListModel());
for(int i = 0; i < 1000; i++) {
list.add("a"+i);
}
refill.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
DefaultListModel dtm = (DefaultListModel)jList1.getModel();
dtm.removeAllElements();
for(String s : list) {
dtm.addElement(s);
}
}
});
frame.add(panel);
panel.setLayout(new BorderLayout());
panel.add(jList1, BorderLayout.CENTER);
panel.add(refill, BorderLayout.SOUTH);
frame.setSize(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
The problem is cause by removing all elements in the model when the first element is selected. The way it is implemented, when an index is selected and is removed, for some reason it generates a selectionChanged event. If another index is selected while another is deleted (even if it meant element shifting), it doesn't generate a selectionChanged event.
The removal is implemented in a way that it periodically removes the first element, while the selection index remains unchanged. So for the case of index 0 being selected, it generates 1000 selectionChanged events, which must be handled by the EDT and listeners. If you select another index, only 1 event is generated. That is significantly less overhead.
Before the repopulating while index 0 is selected, try manually setting the selection to index 1:
if(jList1.getSelectedIndex() == 0){
jList1.setSelectedIndex(1);
}
I think there is no need to worry if there is only one element in the list - it shouldn't do anything to set index greater that element count. But that may be implementation-specific.
For some reason, clearSelection() will cause selectionChanged events to be generated for repopulating an empty list.
logical & better could (just to avoiding mistakes from typos) be to add / remove / modify Items directly in XxxListModel,
for example
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Testing extends JFrame {
private static final long serialVersionUID = 1L;
private DefaultListModel listModel = new DefaultListModel();
private JList list = new JList(listModel);
private int currentSelectedRow = 0;
private int xX = 0;
public Testing() {
setLocation(400, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
for (int x = 0; x < 51; x++) {
listModel.addElement("" + x);
xX++;
}
JScrollPane sp = new JScrollPane(list);
final JViewport vp = sp.getViewport();
add(sp, BorderLayout.CENTER);
/*JButton btn = new JButton("Get Row:");
add(btn, BorderLayout.SOUTH);
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
try {
int goToRow = Integer.parseInt(JOptionPane.showInputDialog(getContentPane(), "Go To Row:"));
Rectangle r = list.getCellBounds(goToRow, goToRow);
if (goToRow > currentSelectedRow) {
r = list.getCellBounds(goToRow - 1, goToRow - 1);
int vph = vp.getExtentSize().height;
r.y += vph;
}
list.scrollRectToVisible(r);
list.setSelectedIndex(goToRow);
currentSelectedRow = goToRow;
} catch (Exception e) {
}
}
});*/
JButton btn1 = new JButton("Reset Model CastingModel");
add(btn1, BorderLayout.NORTH);
btn1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
DefaultListModel model = (DefaultListModel) list.getModel();
model.removeAllElements();
for (int x = 0; x < 51; x++) {
model.addElement("" + (x + xX));
xX++;
}
//list.setModel(model);
}
});
JButton btn2 = new JButton("Reset Model directly from Model");
add(btn2, BorderLayout.SOUTH);
btn2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
listModel.removeAllElements();
for (int x = 0; x < 51; x++) {
listModel.addElement("" + (x + xX));
xX++;
}
}
});
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Testing().setVisible(true);
}
});
}
}
EDIT list.clearSelection(); hasn't any issue, everything moreover than 1k rows caused with desribed issue by OPs
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Testing extends JFrame {
private static final long serialVersionUID = 1L;
private DefaultListModel listModel = new DefaultListModel();
private JList list = new JList(listModel);
private int currentSelectedRow = 0;
private int xX = 0;
public Testing() {
setLocation(400, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
for (int x = 0; x < 999; x++) {
listModel.addElement("" + x);
xX++;
}
JScrollPane sp = new JScrollPane(list);
final JViewport vp = sp.getViewport();
add(sp, BorderLayout.CENTER);
JButton btn1 = new JButton("Reset Model CastingModel");
add(btn1, BorderLayout.NORTH);
btn1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
list.clearSelection();
DefaultListModel model = (DefaultListModel) list.getModel();
model.removeAllElements();
for (int x = 0; x < 999; x++) {
model.addElement("" + (x + xX));
xX++;
}
//list.setModel(model);
}
});
JButton btn2 = new JButton("Reset Model directly from Model");
add(btn2, BorderLayout.SOUTH);
btn2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
list.clearSelection();
listModel.removeAllElements();
for (int x = 0; x < 999; x++) {
listModel.addElement("" + (x + xX));
xX++;
}
}
});
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Testing().setVisible(true);
}
});
}
}