JFrame window resizing on every compile. Different results every time - java

Erm, I'm not too sure what's happening... For the life of me I didn't even try and debug after running the application several times in a row from the IDE. I decided to come straight over here and explain what I consider to be odd.
I'm trying to create a chessboard with tan and beige squares, I have a JFrame window set to 1024x1024 in size, so a square. I also am using a gridLayout of 8x8.
Every time I run the application I might get a grid of say 6x8, the next run a 5 x8, or next a 7x7.
Not sure what's going on... Any help would be sweet!
public class ChessBoard extends JFrame{
private final JFrame board = new JFrame();
private final JButton button = new JButton();
private final GridLayout grid = new GridLayout(8, 8);
public ChessBoard(){
board.setSize(1024, 1024);
board.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
board.setVisible(true);
board.setLayout(grid);
AddGridColors();
}
private void AddGridColors(){
Color tanColor = new Color(210, 180, 140);
Color beigeColor = new Color(245, 245, 220);
JPanel[] panelArray = new JPanel[63];
int panelArrayIndex;
for(panelArrayIndex = 0; panelArrayIndex < 63; ++panelArrayIndex){
panelArray[panelArrayIndex] = new JPanel();
if(panelArrayIndex == 0){
panelArray[panelArrayIndex].setBackground(tanColor);//tan
panelArray[panelArrayIndex].add(new JLabel("square"+panelArrayIndex));
board.add(panelArray[panelArrayIndex]);
}
if(panelArrayIndex > 0){
if(panelArrayIndex % 8 == 0){
panelArray[panelArrayIndex].setBackground(beigeColor);
panelArray[panelArrayIndex].add(new JLabel("square"+panelArrayIndex));
board.add(panelArray[panelArrayIndex]);
}
if(panelArray[panelArrayIndex-1].getBackground().equals(tanColor)){
panelArray[panelArrayIndex].setBackground(beigeColor);
panelArray[panelArrayIndex].add(new JLabel("square"+panelArrayIndex));
board.add(panelArray[panelArrayIndex]);
}else{
panelArray[panelArrayIndex].setBackground(tanColor);
panelArray[panelArrayIndex].add(new JLabel("square"+panelArrayIndex));
board.add(panelArray[panelArrayIndex]);
}
}
}
}
Is this normal, am I missing something incredibly obvious?

From my above comment:
Could you try moving the call to AddGridColors(); right before setSize(1024, 1024);
This could be because you're calling setVisible(true); before you've added all your elements to the JFrame and thus, causing issues like this one.
setVisible(true); should be the last line on your program.
Btw follow the Java naming conventions
firstWordLowerCaseVariable
firstWordLowerCaseMethod()
FirstWordUpperCaseClass
ALL_WORDS_UPPER_CASE_CONSTANT
I said this:
Also, shouldn't your for-loop be from 0 to 64 instead of 0 to 63?
Because your for-loop is going from 0-63 (without including 63)
for(panelArrayIndex = 0; panelArrayIndex < 63; ++panelArrayIndex){
Should be either:
for(panelArrayIndex = 0; panelArrayIndex < 64; ++panelArrayIndex){
Or
for(panelArrayIndex = 0; panelArrayIndex <= 63; ++panelArrayIndex){
But the same should go for your panel's array (There are 63 elements, not 64):
JPanel[] panelArray = new JPanel[63];
Should be:
JPanel[] panelArray = new JPanel[64];

Related

How do I make a CardLayout work with an arbitrary amount of cards?

I am trying to make cardLayout work with an arbitrary amount of cards, meaning I will need some kind of a loop through all the objects I have. Now I tried and I made it work with manually created JPanels but once I put a loop in it doesn't work.
#SuppressWarnings("serial")
public class ClassCardLayoutPane extends JPanel{
JPanel cards;
public ClassCardLayoutPane() {
initialiseGUI();
}
private void initialiseGUI() {
String[] listElements = {"A2", "C3"};
cards = new JPanel(new CardLayout());
JLabel label = new JLabel("Update");
add(label);
JList selectionList = new JList(listElements);
selectionList.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent evt) {
if (!evt.getValueIsAdjusting()) {
label.setText(selectionList.getSelectedValue().toString());
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, label.getText());
}
}
});
// The panels created by this loop don't work, the cards get stuck on the first one
/*
for (int i = 0; i < listElements.length-1; i ++) {
JPanel temp = new JPanel();
temp.add(new JLabel(i+""));
cards.add(temp, listElements[i]);
}*/
JPanel card1 = new JPanel();
card1.add(new JTable(20,20));
JPanel card2 = new JPanel();
card2.add(new JTable(10,20));
cards.add(card1, listElements[0]);
cards.add(card2, listElements[1]);
//the panels here do work. I don't know what I'm doing wrong
add(selectionList);
add(cards);
}
public static void main(String[] args) {
JFrame main = new JFrame("Win");
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setPreferredSize(new Dimension(1366, 768));
main.getContentPane().add(new ClassCardLayoutPane());
main.pack();
main.setVisible(true);
}
}
Okay so the commented out for loop is what doesn't work for me which has me really confused? Can someone explain to me why it doesn't work and how I could make it work? By the way, listElements can be a different size, that's what I'm trying to get working because eventually, listElements will start off as a LinkedList, so when I create the array for the ListItems, it will be a different size every time because I don't know how many items there will be. Can someone please help me make this work? By "It doesn't work", I mean when I use the loop, the JPanel gets stuck on the very first card and doesn't switch to the next card anymore! There is no error message, the program runs fine but it doesn't do what it's meant to do which is switch cards! Note that when I do them individually, the program works perfectly! Thank you.
Okay so the commented out for loop is what doesn't work for me which has me really confused?
Well the first thing you should be doing is adding debug code to the loop to see if unique card names are being used.
If you did that then you would notice the following problem:
for (int i = 0; i < listElements.length-1; i ++) {
Why are you subtracting 1 fro the list length? You only ever add one panel to the CardLayout.
The code should be:
for (int i = 0; i < listElements.length; i ++) {
When code doesn't execute as you think you need to add debug code or use a debugger to step through the code to see if the code executes as you expect.
You can't just always stare at the code.

Stupid For loop implementation

Using java.awt and javax.swing I've been making a small GUI which will show multiple entries in a JPanel. After successfully displaying a single entry with default text, I started trying to implement a for loop to create multiple entries from a handful of arrays and am having difficulty loading the text strings that label each component. After adding the for loop and arrays I now just get a single black border around a small space with no data.
Here's the code that I'm working with specifically:
package myInterfaceComponents;
import java.awt.*;
public class ListOfEntries extends JComponent {
//instance variables
//worked until arrays added
String[] telephones = {"5551234567", "5557654321", "5555671234"};
String[] names = {"Emily", "Billy Bob", "Wiley Coyote"};
String[] periods = {"2p - 3p", "1a - 5a", "4:30p - 11p"};
private JLabel telephone = new JLabel();
private JTextField name = new JTextField();
private JButton period = new Button();
private StatusCombo serviceCycle = new StatusCombo();
private AreaCombo area = new AreaCombo();
//constructors
public ListOfEntries() {
setLayout(new GridLayout(2, 3));
for (int x = 0; x == 2; x++) { //worked until added
telephone.setText(telephones[x]); //worked until added
name.setText(names[x]); //worked until added
period.setText(periods[x]); //worked until added
add(telephone);
add(name);
add(area);
add(period);
add(serviceCycle); } //worked until add: "}"
Border line = BorderFactory.createLineBorder(Color.BLACK);
Border titled = BorderFactory.createTitledBorder(line, "Day: DD MMM YYYY");
setBorder(visible);
setVisible(true); }
}
Obviously I'm doing something wrong with the arrays, or setting the components, but after multiple attempts & google searches I'm missing something. Any help is much appreciated.
I haven't actually tried running your program, but I did notice your loop:
for (int x = 0; x == 2; x++) { //worked until added
telephone.setText(telephones[x]); //worked until added
name.setText(names[x]); //worked until added
period.setText(periods[x]); //worked until added
add(telephone);
add(name);
add(area);
add(period);
add(serviceCycle); }
In this loop, you are initializing the counter variable "x" to 0, but then in the next statement you have: x == 2, which will run the loop only when x is equal to 2, and since x was initialized to be 0, this loop will never run. Try changing the statement x == 2 to x < 2 and see if this helps at all.

Initializing two-dimensional JPanel arrays using a for loop

I'm relatively new to java and i'm trying to do an assignment for school. In my assignment i'm supposed to make a GUI program that makes a 8 by 8 red and black colored checkerboard. The only problem (so far) that i'm having is initializing a two-dimensional array of JPanels. i'm getting this error when using eclipse:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 7
This doesn't give an error until i try to run the code. It says the error is occurring in the body of this for loop:
JPanel[][] panel = new JPanel[7][7];
for (int i = 0; i <= panel.length; i++){
panel[i][0] = new JPanel();
panel[i][1] = new JPanel();
panel[i][2] = new JPanel();
panel[i][3] = new JPanel();
panel[i][4] = new JPanel();
panel[i][5] = new JPanel();
panel[i][6] = new JPanel();
panel[i][7] = new JPanel();
}
This does work if i don't use a for loop but i really don't want to put in 64 different statements do do this. I double checked and the panel.length does give the value 7 (which is what i wanted) and did not work even when i physically put in 7. I don't have any syntax error is my code, but i still get the error. Is there some other way i should go about doing this? Thanks in advance. Remember i'm new to this.
"make a GUI program that makes a 8 by 8 red and black colored checkerboard. The only problem (so far) that i'm having is initializing a two-dimensional array of JPanels.".
If all you need to do is make the board, with no other conditions, why not just use a GridLayout
JPanel mainPanel = new JPanel(new GridLayout(8, 8));
for (int i = 0; i < 64; i++){
JPanel panel = new JPanel();
// alternate background colors with a predefined boolean and an if
mainPanel.add(panel);
}
Three things:
A checkboard is 8×8, so you really want panel.length to be 8, no?
A standard for loop uses < for the test, not <=.
If you use two nested loops, you don't need to repeat new JPanel() 8 times.
Result:
JPanel[][] panel = new JPanel[8][8];
for (int i = 0; i < panel.length; i++) {
for (int j = 0; j < panel[i].length; j++) {
panel[i][j] = new JPanel();
}
}

Java: Animated Sprites on GridLayout Part 2

This is a continuation from my last post Java: Animated Sprites on GridLayout. Thanks to a reply, it gave me an idea in where I just had to insert a loop in the trigger condition and call pi[i].repaint() in it. So far it works. Though I tried to integrate it to my game which composed of multiple sprites, it had no improvement in it. Without the animation, the sprites show on the grid with no problems. I inserted the animation loop in the GridFile class and it didn't show. I also tried to insert the animation loop in the MainFile, it showed irregular animations, kinda like a glitch. Can someone tell me where did I went wrong? Ideas are welcome.
MainFile class
public class MainFile {
JFrame mainWindow = new JFrame();
public JPanel gridPanel;
public MainFile() {
gridPanel= new GridFile();
mainWindow.add(gridPanel,BorderLayout.CENTER);
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWindow.setSize(700,700);
mainWindow.setResizable(false);
mainWindow.setVisible(true);
}
public static void main(String[]args){
new MainFile();
}
}
GridFile class
public class GridFile extends JPanel{
ImageIcon gameBackground = new ImageIcon(getClass().getResource("Assets\\GridBackground.png"));
Image gameImage;
int[] pkmArray = new int[12];
int random = 0;
Pokemon[] pkm = new Pokemon[36];
JPanel[] pokeball = new JPanel[36];
int j = 0;
public GridFile(){
setLayout(new GridLayout(6,6,6,6));
setBorder(BorderFactory.createEmptyBorder(12,12,12,12));
gameImage = gameBackground.getImage();
for(int i = 0;i < 36;i++){
do{
random = (int)(Math.random() * 12 + 0);
if(pkmArray[random] <= 3){
pokeball[i] = new Pokemon(random);
pokeball[i].setOpaque(false);
pokeball[i].setLayout(new BorderLayout());
pkmArray[random]++;
}
}while(pkmArray[random] >= 4);
add(pokeball[i],BorderLayout.CENTER);
}
while(true){
for(int i = 0; i < 36; i++){
pokeball[i].repaint();
}
}
}
public void paintComponent(Graphics g){
if(gameImage != null){
g.drawImage(gameImage,0,0,getWidth(),getHeight(),this);
}
}
}
Use a swing Timer for the repainting, and give a bit time between the frames for swing to do the painting work. There's no point trying to draw faster than what could be displayed anyway. If you have the animation loop in main(), the repaint manager will try to drop some of the repaint requests that appear close to each other, which can be the cause of the irregular animation you see.
You should create and access swing components only in the event dispatch thread. You current approach is breaking the threading rules.
Addition: When the animation loop is where you have it now, the GridFile constructor never returns, which explains that you'll see nothing because the code never gets far enough to show the window.

JScrollPane always clears my Panel

Hy.. I have a JPanel, and in this contentPanel I added some other custom panels and give them locations etc. So now I added a JScrollPane to the contentPanel and always when I scroll down it clears my contentPanel, but the panels are still there but not visible...
How can I make them visible again?
That's my code to add the Panel into the contentPanel. The x,y,j are some settingsstuff for the location because I have an fixed window.
private void reloadContentPanel() {
int x = -200, y = 0, j = 1, row = 4;
EventPanel panel = null;
int i;
for(i=0; i < this.images.size();i++)
{
panel = new EventPanel(this.images.get(i).getAbsolutePath(),
this.images.get(i).getName());
panel.setLocation(x+(j*200), y);
j++;
if(i == row) {
x = -200;
y += 205;
j = 1;
row += 5;
}
this.contentPanel.add(panel);
}
this.repaint();
}
Thanks
it sounds like you are not using a LayoutManager correctly.
after creating your JFrame (i'm guessing within your constructor) add the following (for example):
this.setLayout(new FlowLayout());
this will certainly not be the best layout manager for what you are trying to do but will stop the add calls from overriding the displayed component.
you will need to read further about LayoutManagers
besides this, it's not really advisable to extend JFrame. It's better practice to treat JFrame as a member of your class just like all the other components.
I have the answer! :)
I use a GridLayout not a FlowLayout, so it's fine and it automatically refreshes the panels =)

Categories