Hi I have to do a lottery with numbers when I first choice in a panel when I press Start it should serve me a panel with figures given them passed to the constructor panel but while I normally displays the panel the numbers in the JTextField does not apper.
The code when I press the button to make a panel with numbers at the function that returns to 2nd table numbers I put here a system.out and she shows them normally underneath its constructor passing the table as a parameter.
if (source == start) {
try {
int numbers[][] = fucts.takeBulletin();
RMIClient r=new RMIClient( numbers,1);
}catch() {
}
}
heare is the constructor code
public RMIClient(int [][]numbs,int a) {
super("!!!!!!!!!!!!!!!BINGO!!!!!!!!!!!!!!!!!!");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Container pane = getContentPane();
GridLayout layout=new GridLayout(7 , 7);
pane.setLayout(layout);
pane.add(numB);
pane.add(numI);
pane.add(numN);
pane.add(numG);
pane.add(numO);
pane.add(num13);
for (int row = 0; row < numbs.length; row++) {
for (int col = 0; col < numbs[row].length; col++) {
pane.add(new JTextField(""+numbs[row][col])); <----- is nedd " "+
}
}
setContentPane(pane);
pack();
}
I can not understand why they do not pass the values from the table in textfield , is show me empty textfields
If it is a JApplet, try to move the whole content of the constructor into the init() method.
The constructor could save the int[][] numbs to an instance variable, and the init() method will see it.
int[][] numbs;
public RMIClient(int[][] numbs, int a) {
this.numbs = numbs;
}
public void init() {
...
}
Related
Ok so I am trying to make a chess game in swing. I have a program that creates a 2d array of JButton's 8x8. I then create them all in a loop doing stuff like going back and forth between white/black and adding an action event. The problem i am having is that each button has the same action event and it is the event that is created last I.E. button on Row 8 column H is the action listener for all of the buttons in the array. Here is a snippet of code that is where I am creating the buttons and adding them.
I also have an Enum Columns that just goes from int to character 1 to H for example. selectPosition and targetPosition are objects that have two members columns and rows.
public void initializeGui(boolean isWhite) {
boolean shouldBeWhite = true;
for(int i = 0; i< 8; i++){
for(int j = 0; j < 8; j++){
column = i+1;
row = j+1;
JButton square = new JButton();
square.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
final int thisRow = row;
final int thisColumn = column;
selectPosition.setColumn(Columns.getColumnsFromInt(thisColumn));
selectPosition.setRow(thisRow);
if(isSelecting){
System.out.print("Selecting square to move. Row: " + thisRow + " Column: " + Columns.getColumnsFromInt(thisColumn));
selectPosition.setColumn(Columns.getColumnsFromInt(thisColumn));
selectPosition.setRow(thisRow);
} else{
System.out.print("Targeting square to move to. Row: " + thisRow + " Column: " + Columns.getColumnsFromInt(thisColumn) + "\n");
targetPosition.setColumn(Columns.getColumnsFromInt(thisColumn));
targetPosition.setRow(thisRow);
}
System.out.println("");
isSelecting = !isSelecting;
}
});
if(shouldBeWhite){
square.setBackground(Color.WHITE);
shouldBeWhite = false;
}else{
square.setBackground(Color.BLACK);
shouldBeWhite = true;
}
if (j == 7){
shouldBeWhite = !shouldBeWhite;
}
chessBoardSquares[i][j] = square;
gui.add(chessBoardSquares[i][j]);
}
}
if(isWhite){
setInitialPiecesWhiteStart();
}else{
setInitialPiecesBlackStart();
}
}
Further up as a member of this class are the following:
int column = 0, row = 0;
When I click on any of these buttons i see printed
Selecting square to move. Row: 8 Column: H
Targeting square to move to. Row: 8 Column: H
Selecting square to move. Row: 8 Column: H
Targeting square to move to. Row: 8 Column: H
and so on. My question is why are these buttons all given the same action event? My logic walk through would be something like create the first button set column = i+1 and row = j+1 then add an action listener with an action event that sets the current row/column values to the inner final variables and then prints out the thisRow and thisColumn associated with that action event. Am i overriding the values at the end or do i have the scope wrong? Basically how am i creating these buttons actions listeners incorrectly?
You could...
Use the actionCommand API to pass information between the button and the ActionListener...
JButton btn = new JButton();
btn.setActionCommand(row + "x" + column);
btn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
//...
}
});
The problem here is you're relying on String parsing to extract the values, which can get messy quickly
You could...
Create a custom ActionListener which takes the values you want to use...
public class SquareActionListener implements ActionListener {
private int column;
private int row;
public SquareActionListener(int row, int column) {
this.row = row;
this.column = column;
}
#Override
public void actionPerformed(ActionEvent e) {
//...
}
}
This de-couples the ActionListener from the rest of the code and provides you the information you need, although, you may need to pass additional information (such as the model) as well for it to work
You could...
Make use of the Action API which is designed to be provide self contained units of work, it's generally a more re-usable solution, but might be a little beyond what you need right now
public class SquareAction extends AbstractAction {
private int column;
private int row;
public SquareAction(int row, int column) {
this.row = row;
this.column = column;
}
#Override
public void actionPerformed(ActionEvent e) {
//...
}
}
This looks alot like the last suggestion, but instead of adding it as the button's ActionListener, you actually apply it to the button directly...
JButton btn = new JButton(new SquareAction(row, column));
The button then uses other properties (which I've not set) to set itself up
I had the same issue when making a tic-tac-toe game. I used each button's hashcode to trace back which button was actually pushed. This is what my button setup looked like:
hashcodes= new ArrayList<Integer>();
for (int i=1;i<=9;i++) {
JButton button = new JButton();
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setHash(button.hashCode());
testWinner();
testDraw();
}
});
hashcodes.add(button.hashCode());
panel.add(button);
}
}
private void setHash(int hashcode) {
for (int h:hashcodes) {
if (h==hashcode) {
//do stuff
}
}
}
This is my Test class, and it works perfectly.
public class Test extends javax.swing.JFrame {
private javax.swing.JButton[][] buttons;
private final int ROW = 8;
private final int COLUMN = 8;
public Test() {
initComponents();
}
private void initComponents() {
this.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
this.setExtendedState(javax.swing.JFrame.MAXIMIZED_BOTH);
this.buttons = new javax.swing.JButton[ROW][COLUMN];
this.setLayout(new java.awt.GridLayout(ROW, COLUMN));
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COLUMN; j++) {
final int row = i;
final int column = j;
buttons[i][j] = new javax.swing.JButton(
String.format("Button %d-%d", i, j));
buttons[i][j].addActionListener(new java.awt.event.ActionListener() {
#Override
public void actionPerformed(java.awt.event.ActionEvent e) {
// System.out.println(
// String.format("You have just pressed the button at row %d and column %d", row, column));
javax.swing.JOptionPane.showMessageDialog(
Test.this, String.format("You have just pressed the button at row %d and column %d", row, column));
}
});
this.add(buttons[i][j]);
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
new Test().setVisible(true);
}
}
My first question here. Already got a lot of help but now I don't know how to do.
My code:
package view;
import javax.swing.*;
public class OptionPlayerNames {
JPanel playerPanel = new JPanel();
JTextField playerNames = new JTextField();
public OptionPlayerNames() {
for (int i = 0; i < 8; i++) {
// JTextField playerNames = new JTextField();
playerPanel.add(new JLabel("Player " + (i + 1)));
playerPanel.add(playerNames);
}
playerPanel.setLayout(new BoxLayout(playerPanel, BoxLayout.Y_AXIS));
playerPanel.add(Box.createHorizontalStrut(5));
}
public JPanel getPanel(){
return playerPanel;
}
public String getPlayerNames() {
return playerNames.getText();
}
I want to have 8 Jlabels with just under it 8 JTextFields for user input.
Then get the text of the textfields.
Now I get only 1 text from 1 textField. Off course I only add 1 field.
When I put the JTextField under the for loop I get what I want but how to I get the text from all the JTextFields then? playerNames is then not known in the getter.
Thank you for your help.
You can do as follows, creating a Listof JTextField:
JPanel playerPanel = new JPanel();
List<JTextField> playerNames = new ArrayList<JTextField>();
public OptionPlayerNames() {
for (int i = 0; i < 8; i++) {
JTextField playerName = new JTextField();
playerPanel.add(new JLabel("Player " + (i + 1)));
playerPanel.add(playerName);
playerNames.add(playerName);
}
playerPanel.setLayout(new BoxLayout(playerPanel, BoxLayout.Y_AXIS));
playerPanel.add(Box.createHorizontalStrut(5));
}
public JPanel getPanel() {
return playerPanel;
}
public String getPlayerNames() {
String output = "";
// Compound you exit from the playerNames List
// Or better, return a List of String
return output;
}
You need to declare a Vector or array of JTextField as an instance variable (not just one, as you've commented out) and fill it in as you loop. Then you have random (arbitrary) access to any text value. Conveniently, the index i is already there for you to index into the array.
There should be a tip-off that the type: JTextField is singular, but your variable name: playerNames is plural. :-)
Note that getPlayerNames() also needs to be re-done to handle an array not a single field.
While this will work, ultimately, the whole code block isn't good separation of Model & View, so as you advance in programming, be sure to pay attention to that concept.
In short, I would like to accumulate a bunch of JButton's to an array, and create one ActionListener class for the array.
I'm trying to create a calculator, and all the numbered buttons, such as "6", are in a JButton array, because I would like to have it input the set number into a temporary int, and it would be easier to create one method, instead of 10. I also have 40 other buttons, that I would like to apply the same principal to, but in a different array, so it would be much faster and easier to put these into a couple of ActionListener methods where the buttons data is implemented to that method.
this is the code I have:
private JButton num0, num1, num2, num3, num4, num5, num6, num7, num8, num9;
private JButton numArray[] = {num0, num1, num2, num3, num4, num5, num6, num7, num8, num9};
public GUI(){
numArray.AddActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
}
});
}
You can consider the proposal of Newb Monad. However, you can use the same listener for all your buttons, as in the following example.
public static void main(String[] args) {
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof JButton) {
String text = ((JButton) e.getSource()).getText();
JOptionPane.showMessageDialog(null, text);
}
}
};
JPanel panel = new JPanel(new GridLayout(4,3));
JButton[] array = new JButton[10];
for (int i = 0; i < array.length; i++) {
array[i] = new JButton(String.valueOf(i));
array[i].addActionListener(listener);
panel.add(array[i]);
}
JOptionPane.showMessageDialog(null, panel);
}
You have the right idea. However, array objects do not have an addActionListener() method. You must add an action listener to each JButton individually. You can use the same listener for every button, but then you have to figure out which button was clicked inside the actionPerformed() method. IMO, a cleaner solution is to assign a separate listener to each JButton because that way each ActionListener can know which number is pressed without checking the source of the event. For example, you can create a NumberButtonListener class which takes an int as the only argument to its constructor. You can then create the JButtons and the corresponding NumberButtonListeners at the same time in a small loop.
This seems to work well for me.
I essentially loop through all of the buttons while checking it against the action (e.getSource()).
public void actionPerformed(ActionEvent e){
//loop through allbuttons to check if clicked
for(int i = 0; i < buttonArr.length; i++){
for(int j = 0; j < buttonArr[0].length; j++){
if(e.getSource() == buttonArr[i][j]){
//do stuff
}
}
}
}
I had a similar problem with a 2D array of buttons for a game of "Connect Four". I was able to use a for loop inside ActionListener to test which of my buttons had been pushed. The key was modifying the toString() method from my button class to supply the array element as a string:
Within the JPanel class definition:
...
discs = new RoundButton[6][7]; //my 2D array
...
public class RoundButton extends JButton {
...
public String toString() {
return "discs["+i+"]["+j+"]";
}
...
}
private class ButtonListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent event) {
for (int i = 0; i < discs.length; i++){
for (int j= 0; j < discs[i].length; j++){
if (event.getSource() == discs[i][j]){
discs[i][j].setIcon(yellowDisc); //my particular action for that button
}
}
Sorry this is messy. I've never posted on here before.
Lets say you have a GridLayout of JButtons in an NxN grid, in code such as this:
JPanel bPanel = new JPanel();
bPanel.setLayout(new GridLayout(N, N, 10, 10));
for (int row = 0; row < N; row++)
{
for (int col = 0; col < N; col++)
{
JButton b = new JButton("(" + row + ", " + col + ")");
b.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
}
});
bPanel.add(b);
}
}
How would one access each button individually in the grid to change the button's name through setText()? This needs to be done outside of actually pressing the button in question.
Because each button in instantiated locally as "b", a globally accessible name for each button is not possible at current. What could be done to access each button independently? Could an array like JButton[][] hold references to all the buttons? How can this be set up in the code above?
Any input is appreciated.
Thanks.
you can,
1) putClientProperty
buttons[i][j].putClientProperty("column", i);
buttons[i][j].putClientProperty("row", j);
buttons[i][j].addActionListener(new MyActionListener());
and
public class MyActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JButton btn = (JButton) e.getSource();
System.out.println("clicked column " + btn.getClientProperty("column")
+ ", row " + btn.getClientProperty("row"));
}
2) ActionCommand
You can create an array (or list or something else) to store all the buttons. Or you can use public Component[] getComponents() method of the bPanel (Container).
This is what I currently have but its not not showing the results in two textareas..
Right now all it shows is one textarea with Odd numbers only. I'm not sure why the even numbers wont show. Any help is appreciated Thanks!
static TextFileInput inFile;
static String inFileName = "lab12.txt";
static JFrame myFrame;
static Container cPane;
static TextArea even, odd;
public static void main(String[] args) {
initialize();
readNumbersFromFile(inFileName);
}
public static void initialize() {
inFile = new TextFileInput(inFileName);
even = new TextArea();
odd = new TextArea();
myFrame=new JFrame();
myFrame.setSize(400,400);
myFrame.setLocation(200, 200);
myFrame.setTitle("test");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setVisible(true);
}
public static void readNumbersFromFile(String fileName){
String[] num = new String[20];
String line;
line = inFile.readLine();
for(int i = 0; i < inFile.getLineCount(); i++){
num[i] = line;
line = inFile.readLine();
}
cPane = myFrame.getContentPane();
cPane.add(even);
cPane.add(odd);
for(int i = 0; i < inFile.getLineCount(); i++){
if(Integer.parseInt(num[i]) % 2 == 0)
even.append(num[i] + "\n");
else
odd.append(num[i] + "\n");
}//for
myFrame.setVisible(true);
}//readSSNsFromFile
It is better you build the panel and division the panel by the row and column and add this panel on the frame.
'cPane' will have a BorderLayout by default. Adding components to a BorderLayout with no constraints will result in the component being put in the CENTER constraint. Any area of a BorderLayout can only accommodate one component.
A better general approach is to instantiate a JPanel with an appropriate layout, add the components to the JPanel, then either add that JPanel to the content pane, or set it as the content pane.