I think some how my actionListeners are messed up. I am supposed to have two blocks of buttons.
First panel is 16 buttons x 16 buttons(256 buttons total). Second panel is 8 buttons x 2 buttons(16 buttons total) I am able to pass "blue" from "ColorChooser" to both panels.
However, the second panel should turn RED. NOT BLUE. My second issue - Panel 2 looks correct. It starts at 1 and goes to 16. However, Panel 1 starts at 17 and goes to 256. Please and thank you for any help.
I was also wondering why my tool tips for the button arrays do not work?
Thanks Again!
example of what I mean
final JFrame MaineFrame = new JFrame("Kola Color Crapper");
MaineFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MaineFrame.setPreferredSize(new Dimension(400, 400));
final JFrame PatternGeneratorFrame = new JFrame("Pattern Generator");
PatternGeneratorFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ActionListener PatternMakerActionListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
PatternGeneratorFrame.setVisible(true);
}
};
JButton PatternMakerBtn = new JButton("Make Pattern");
PatternMakerBtn.addActionListener(PatternMakerActionListener);
PatternMakerBtn.setToolTipText("This will allow you to create your own patterns 1 frame at a time.");
JPanel contentPane = new JPanel();
ActionListener myActionListener = new ActionListener() {
public void actionPerformed(ActionEvent aef) {
if (aef.getSource() instanceof JButton) {
((JButton) aef.getSource()).setBackground(ColorChooser.PassColor);
}
}
};
ActionListener ColorChooserActionListener = new ActionListener() {
public void actionPerformed(ActionEvent aee) {
if (aee.getSource() instanceof JButton) {
((JButton) aee.getSource()).setBackground(Color.red);
}
}
};
JButton button[] = new JButton[256];
JPanel GridPanel = new JPanel();
GridPanel.setBorder(BorderFactory.createLineBorder(Color.blue, 2));
GridPanel.setLayout(new GridLayout(16, 16, 10, 10));
for (int i = 0; i < button.length; i++) {
button[i] = new JButton(Integer.toString(i + 1));
button[i].addActionListener(myActionListener);
GridPanel.add(button[i]);
GridPanel.setToolTipText("lets make noise.");
}
contentPane.add(GridPanel);
JButton ColorPickerBtn[] = new JButton[16];
JPanel ActionPanel = new JPanel();
ActionPanel.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 6));
ActionPanel.setLayout(new GridLayout(2, 8, 0, 10));
for (int l = 0; l < 16; l++) {
ColorPickerBtn[l] = new JButton(Integer.toString(l+ 1));
ColorPickerBtn[l].addActionListener(ColorChooserActionListener);
ColorPickerBtn[l].setToolTipText("Choose the color you would like to use. * Colors 1-8 are static. You may change colors 9-16.");
ActionPanel.add(button[l]);
}
contentPane.add(ActionPanel);
MaineFrame.getContentPane().add(PatternMakerBtn);
PatternGeneratorFrame.setContentPane(contentPane);
PatternGeneratorFrame.pack();
PatternGeneratorFrame.setVisible(false);
MaineFrame.pack();
MaineFrame.setVisible(true);
;
}
});
}
}
}
My approach to this problem would be to just use one single ActionListener that would be listening to the entire frame.
Related
Hi guys I'm using Eclipse and I'm trying to create a Connect4 Game Grid , which is an JPanel gridArray [6] [7]. I later add the different Panels for buttons and the grid into a main panel and add it into my frame.
My Problem:
I want to fill the gridArray JPanel with Pictures of an empty field(white color) but first of all i want to create a new Panel and insert it into my gridArray through a loop until gridArray has all 42 Panels inside it and is fully filled. I have my Code below but somehow it doesnt work, although my logic should be fine.
I tried it with using a helper Function to create a new JPanel and call the function for each loop in fillGrid();, basically calling it 42 times but it still wont work...
I will gladly appreciate some help!
package connect4;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class GridTest extends JFrame {
JFrame mainWindow;
JPanel buttonPanel, mainPanel;
JPanel gridPanel;
JPanel emptyPanel;
JPanel panel1;
ImageIcon emptyBox;
JPanel[][] gridArray;
JLabel emptyLabel;
JButton arrow1,arrow2,arrow3,arrow4,arrow5,arrow6,arrow7;
public GridTest() {
createGameGrid();
fillGrid();
}
public void createGameGrid() {
//creating window and mainpanel
mainWindow = new JFrame("Connect 4");
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
//defining top panel with 7 buttons;
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1, 7));
arrow1 = new JButton("V");
arrow2 = new JButton("V");
arrow3 = new JButton("V");
arrow4 = new JButton("V");
arrow5 = new JButton("V");
arrow6 = new JButton("V");
arrow7 = new JButton("V");
buttonPanel.add(arrow1);
buttonPanel.add(arrow2);
buttonPanel.add(arrow3);
buttonPanel.add(arrow4);
buttonPanel.add(arrow5);
buttonPanel.add(arrow6);
buttonPanel.add(arrow7);
//create Grind Panel
gridPanel = new JPanel();
gridPanel.setLayout(new GridLayout(6,7));
mainPanel.add(buttonPanel, BorderLayout.NORTH);
mainPanel.add(gridPanel, BorderLayout.SOUTH);
mainWindow.add(mainPanel);
mainWindow.pack();
mainWindow.setLocationRelativeTo(null);
mainWindow.setVisible(true);
}
private JPanel greateOnePanel(){
//here we need to insert the icon which is in empty box into a newly created panel
//ifirst wanted to insert black panels do ensure it works as intended but it doesnt
JPanel panel = new JPanel();
panel.setBackground(Color.BLACK);
panel.setSize(50,50);
return panel;
}
//here we need to fill the grid with the panels created above from left to right...
public void fillGrid() {
for(int j = 0; j < 6; j++) {
for (int k = 0; k < 7; k++) {
gridPanel.add(greateOnePanel());
}
}
}
public static void main(String[] args) {
new GridTest();
}
}
i tried it with this method using gridArray, but it throws NullPointer Exeptions and wont fill the grid with simple textlabels "Hallo" (just for testing purposes)
public void fillGrid() {
for(int j = 0; j < 6; j++) {
for (int k = 0; k < 7; k++) {
JLabel label = new JLabel("Hallo");
gridArray[j][k] = new JPanel();
gridArray[j][k].setSize(50, 50);
gridArray[j][k].setBackground(Color.RED);
gridArray[j][k].add(label);
gridPanel.add(gridArray[j][k]);
}
}
}
Here is a short, self contained, code that should help with various aspects of the task.
There is no need for a panel in each cell. The only thing it helped with was setting a BG color. That can be done in a label as long as the background is set to opaque.
This code defines a SquareLabel which overrides getPreferredSize() to return the maximum of preferred width and height as the value of both (usually it is the width).
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class SquareLabelGrid {
int rows = 6;
int cols = 7;
JLabel[][] labelArray = new JLabel[cols][rows];
Font bigFont = new Font(Font.SANS_SERIF, Font.BOLD, 30);
Insets labelInsets;
SquareLabelGrid() {
JPanel gameBoard = new JPanel(new GridLayout(rows, cols));
// a border to make the cell boundaries more clear and add
// some space around the text
Border border = new CompoundBorder(
new LineBorder(Color.BLACK),new EmptyBorder(4,4,4,4));
for (int yy = 0; yy < rows; yy++) {
for (int xx = 0; xx < cols; xx++) {
JLabel l = getColoredSquareLabel(xx, yy);
labelArray[xx][yy] = l;
gameBoard.add(l);
l.setBorder(border);
}
}
JOptionPane.showMessageDialog(null, gameBoard);
}
private JLabel getColoredSquareLabel(int x, int y) {
SquareLabel label = new SquareLabel(
String.format("%1s,%1s", (x+1), (y+1)));
label.setFont(bigFont);
label.setOpaque(true); // so we can see the BG color
label.setBackground(Color.ORANGE); // I prefer orange!
// make the GUI less 'crowded'
label.setBorder(new EmptyBorder(4,4,4,4));
return label;
}
public static void main(String[] args) {
Runnable r = () -> {
new SquareLabelGrid();
};
SwingUtilities.invokeLater(r);
}
}
class SquareLabel extends JLabel {
SquareLabel(String label) {
super(label);
}
/* This will create a square component that accounts for the
size of the String / Icon it contains. No guesswork! */
#Override
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
int w = d.width;
int h = d.height;
int sz = w > h ? w : h;
return new Dimension(sz, sz);
}
}
The problem is that you have not initialized the grid array .
Otherwise it will throw Null pointer exception.
JPanel[][] gridArray = new JPanel[6][8];
Also set the preferred size of main panel to make the grids visible .
mainPanel.setPreferredSize(new Dimension(400, 200));
Here is what i can see when I run your code with the modifications mentioned here .
Also please execute it from main with following code .
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new GridTest();
}
});
}
I have been facing this small issue regarding making my JCombobox as dynamic as it can be.For an example, when a selected item in combobox is selected, it will dynamically change the number of buttons accordance to the number of days within the month and be added in the panel
The problem i am facing is that it is not automatically changing the display of the panel , but when i tried to see if the code runs in my console log. it runs smoothly . ive tried my best to find a solution but to no avail.
The main problem is within the actionListener, for e.g if February is selected , it will display 28 buttons, if January is selected, it will display 31 days etc etc but when i run the code, my system.out.println states it runs but my Gui shows no button .
private static JButton method_Btn(int i){
JButton btn = new JButton(Integer.toString(i));
return btn;
}
public static void day(){
JFrame frame = new JFrame();
JPanel topPanel = new JPanel();
JPanel centerPanel = new JPanel();
JButton days = new JButton();
JLabel days_label = new JLabel();
//-- Top Panel
String month[] = {"--Select Month--" , "January", "February"};
JComboBox month_combo = new JComboBox(month);
topPanel.add(month_combo, BorderLayout.PAGE_START);
//-- Center Panel
centerPanel.setLayout(new FlowLayout());
centerPanel.add(days_label);
//------- Change when jcombo is selected
month_combo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
if(month_combo.getSelectedItem().equals("January")){
for(int i = 0;i < 31;i++){
centerPanel.add(method_Btn(i));
}
}
if(month_combo.getSelectedItem().equals("February")){
for(int i = 0;i < 28;i++){
centerPanel.add(method_Btn(i));
}
}
}
});
frame.add(topPanel, BorderLayout.PAGE_START);
frame.add(centerPanel , BorderLayout.CENTER);
frame.setSize(400,400);
frame.setVisible(true);
}
public static void main(String[] args){
day();
}
Addtional Note,
Ive come to realised an additional problem i faced is that it will stack up the number of button created after selecting the month 2nd time. How i solve it is i added centerPanel.removeAll(); and centerPanel.repaint();
month_combo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
int count = 0;
//---- gettind days of month selected in comboBox
if (month_combo.getSelectedItem().equals("February")) {
centerPanel.removeAll();
centerPanel.repaint();
for (int i = 1; i <= 28; i++) {
centerPanel.add(method_Btn(i));
System.out.println("days in feb " + i);
}
centerPanel.revalidate();
}
if (month_combo.getSelectedItem().equals("March")) {
centerPanel.removeAll();
centerPanel.repaint();
for (int i = 1; i <= 31; i++) {
centerPanel.add(method_Btn(i));
}
centerPanel.revalidate();
}
}
});
Hope this help anybody who is in need. :)
You need to revalidate() the component you have added like following:
centerPanel.revalidate();
You need to change the following code:
month_combo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
if(month_combo.getSelectedItem().equals("January")){
for(int i = 0;i < 31;i++){
centerPanel.add(method_Btn(i));
}
}
if(month_combo.getSelectedItem().equals("February")){
for(int i = 0;i < 28;i++){
centerPanel.add(method_Btn(i));
}
}
centerPanel.revalidate(); // Need to add this for revalidation for the component
}
});
I'm in the early stages of making Battleships (just started a computer science degree) and had been using Eclipse on Windows. So far I've just created the grids and have added an actionlistener to the jbuttons so they change colour when clicked.
It works fine when I run it on my Windows PC, however when I try to run it on a mac, it just shows the basic grid and doesn't change colours or anything.
Anyone had a problem like this or can help? I can't figure out why it would work on one and not the other.
Thanks
Here is my code, if that helps (I know it's not elegant or anything right now)
public class BattleshipFrame {
public static void main(String[] args) {
//creating JFrame
JFrame frame = new JFrame("Battleship");
frame.setLayout(new GridLayout(1, 3));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//creating User Panel
JPanel userpanel = new JPanel();
userpanel.setLayout(new GridLayout(10, 10));
userpanel.setSize(400, 400);
//creating JButton array
JButton[] button = new JButton[100];
//putting JButtons in User Panel
for (int i = 0; i < 100; i++) {
button[i] = new JButton();
button[i].setBackground(Color.BLUE);
userpanel.add(button[i]);
//changing colour of buttons when clicked
button[i].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ev) {
Object source = ev.getSource();
if (source instanceof Component) {
((Component) source).setBackground(Color.GREEN);
}
}
});
}
//creating computer panel
JPanel comppanel = new JPanel();
comppanel.setLayout(new GridLayout(10, 10));
comppanel.setSize(400, 400);
//putting JButtons in User Panel
for (int i = 0; i < 100; i++) {
button[i] = new JButton();
button[i].setBackground(Color.BLUE);
comppanel.add(button[i]);
//changing colour of buttons when clicked
button[i].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ev) {
Object source = ev.getSource();
if (source instanceof Component) {
((Component) source).setBackground(Color.GREEN);
}
}
});
}
//creating menu panel
JPanel menupanel = new JPanel();
//creating buttons for menu
JButton save = new JButton("Save");
JButton load = new JButton("Load");
save.setPreferredSize(new Dimension(100, 100));
load.setPreferredSize(new Dimension(100, 100));
//adding buttons to menu panel
menupanel.add(save);
menupanel.add(load);
//adding panels into frame
frame.add(userpanel, BorderLayout.WEST);
frame.add(menupanel, BorderLayout.CENTER);
frame.add(comppanel, BorderLayout.EAST);
frame.setVisible(true);
frame.setSize(2000, 1000);
}
}
As I say, it works perfectly on my Windows Eclipse but not on Mac
I want to create a JLabel of an Array on a button push. I've never done something with Arrays, so maybe it's some sort of training. I tried it, but it won't work. Expected result: Everytime I push the button, would one of the 20 JLabels be created.
Here's my class:
public class JLabelArray {
static JFrame frame;
static JButton button;
public static void main(String[] args) {
final JLabel[] label = new JLabel[20];
//
button = new JButton("push me");
button.setBounds(0, 0, 100, 30);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// This is where a new JLabel should be created
for (int i = 0; i < label.length; i++) {
label[i] = new JLabel("Label" + i);
label[i].setBounds(button.getX(), button.getY()+ 10 + i * 15, 50, 50);
frame.add(label[i]);
frame.revalidate();
frame.repaint();
}
}
});
//
frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setVisible(true);
frame.add(button);
}
}
EDIT: Updated code
EDIT2: Updated for-loop
EDIT3: I reworked the whole question
You should re-validate/repaint when you add Components after the parent container has been validated - this includes not only when you add the JButton (add this prior to setting the JFrame to visible) but also when you add the JLabels
frame.add(label[i]);
frame.revalidate();
frame.repaint();
I would also recommend not using a null layout, rather choose the appropriate LayoutManager: see https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html . If you wish to continue using a null layout, then you should set the added Labels to different positions or they will just overlap each other.
I am designing a GUI to emulate a Nurikabe game (description here). I basically have two JPanels, and when one of buttons in the control panel (panel 2) is clicked, I want to change the buttons in the game panel (panel 1).
Panel 1 has 36 buttons, either non-clickable buttons displaying numbers or clickable blank buttons, all contained in a GridLayout.
Panel 2 has three buttons, new puzzle, check puzzle, and reset current puzzle.
The problem I am running into is that I cannot figure out how to change Panel 1's buttons when either the reset or new puzzle button is clicked without having to display a new window.
Is there a way to do this?
Code: (I have removed the check puzzle and reset puzzle buttons)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SSCCE extends JFrame {
private static final int[][] puzzle1 = { { 0, 1 }, { 1, 0 } };
private static final int[][] puzzle2 = { { 1, 0 }, { 0, 1 } };
private int[][] puzzle;
private JFrame frame;
private JPanel gridPanel;
private JPanel buttonPanel;
public SSCCE(final int puzzleNum) {
frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
if (puzzleNum == 1) {
puzzle = puzzle1;
} else {
puzzle = puzzle2;
}
setLayout(new BorderLayout());
gridPanel = new JPanel(new GridLayout(2, 2));
for (int i = 0; i < this.puzzle.length; i++) {
for (int j = 0; j < this.puzzle[0].length; j++) {
JButton button;
if (this.puzzle[i][j] > 0) {
button = new JButton("" + this.puzzle[i][j]);
} else {
button = new JButton();
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
JButton temp = ((JButton) event.getSource());
if (temp.getBackground() == Color.BLACK) {
// if the button is black, set it to white
temp.setBackground(Color.WHITE);
} else if (temp.getBackground() == Color.WHITE) {
// if the button is white, set it to black
temp.setBackground(Color.BLACK);
}
}
});
}
button.setBorderPainted(false);
button.setContentAreaFilled(false);
button.setOpaque(true);
button.setBackground(Color.WHITE);
gridPanel.add(button);
}
}
buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
JButton changePuzzle = new JButton("New Puzzle");
changePuzzle.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
loadNewPuzzle(puzzleNum);
}
});
buttonPanel.add(changePuzzle);
add(gridPanel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
setTitle("SSCCE");
setLocation(100, 100);
pack();
setSize(150, 150);
}
private void loadNewPuzzle(int puzzleNum) {
if (puzzleNum == 1) {
puzzleNum = 2;
} else {
puzzleNum = 1;
}
// I know this is the wrong way to do it, but I'm not sure how
// to do it.
SSCCE newGame = new SSCCE(puzzleNum);
newGame.setVisible(true);
}
public static void main(String[] args) {
SSCCE game = new SSCCE(1);
game.setVisible(true);
}
}
// suppose you want to make button 2 visible and hide button 1 in panel 1 on clicking
// button 3 from panel 2, you can do something like this:
// add everything you want to display or not in respective panels.
// Then the contents that you dont want to get displayed,make them invisible by calling
setVisible(false).
// Then for button 3 in panel 2, write actionlistener like this:
button3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
// make the visible buttons invisible by using setVisible(false);
// make the invisible buttons visible by using setVisible(true);
}
});
Post some code.
As long as you have references to the JPanels or JButtons, you are free to change them as you see fit. You can remove components, add components etc.
You might use a CardLayout.