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.
Related
I am currently making a GUI that prints a textarea. In this textarea I am required to receive the "weights" for the ID of the variable.
I have created multiple labels showing from ID1: - ID8: & their textfields, and use if statements instead but the with the amount of if and else if.
if (id.size = 1){
id1.setvisible(true);
weight1TField.setvisible(true);
}else if (id.size = 2){
id1.setvisible(true);
weight1TField.setvisible(true);
id2.setvisible(true);
weight2TField.setvisible(true);
}
else if (if.size = 3){
id1.setvisible(true);
weight1TField.setvisible(true);
id2.setvisible(true);
weight2TField.setvisible(true);
id3.setvisible(true);
weight3TField.setvisible(true);
}
So on... untill ID8.
The values are added to the array from a jtable in another Jframe when user has selected the rows(maximum 8 rows).
List<String> ID = new ArrayList<>();
I want to create text fields to allow the user to input their weights and jlabels showing the ID beside the textfield e.g ID: TextField. Image is shown below
ID[i] is replaced with the value in the array if there is one while the rest is hidden if there is no value. How can i create the Jlabels and JTexFields without doing the following below.
ID1.setText(ID[0]);
ID2.setText(ID[1]);
ID3.setText(ID[2]);
ID4.setText(ID[3]);
ID5.setText(ID[4]);
ID6.setText(ID[5]);
ID7.setText(ID[6]);
ID8.setText(ID[7]);
What about instead of using fields (I am not sure you are using fields, but the only thing i can do without more code is guess) to store the components into arrays? I have done an example with JLabels, you can do the same with textfields.
private static int idsCount = 6; //The number of ids. Let's say 6
private JLabel[] labels = new JLabel[8]; // Keep the array as a field. (8 = max capacity)
private void initIDLabels {
for (int i = 0; i < labels.length; i++) {
labels[i] = new JLabel();
// add this font to all labels.
labels[i].setFont(new Font("Tahoma", Font.BOLD, 12));
}
changeLabelsVisibility();
}
private void changeLabelsVisibility() {
// Hide all labels.
for (JLabel label : labels) {
label.setVisible(false);
}
// Show all labels that supposed to be visible
for (int i = 0; i < idsCount; i++) {
labels[i].setVisible(true);
}
}
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];
I have met a serious problem with my Java swing.
This is how I initialize my chart, everything seems fine now, xyChartPanel is declared as a JPanel in the field, I initialize it with the xyChart I just created. When this step is done, I am okay to see the chart (painted to xyChartPanel) centered to the JPanel I am writing code on, see add(xyChartPanel, BorderLayout.CENTER);.
private void initXYChart() {
// Create Chart
xyChart = new XYChartBuilder().width(800).height(800).xAxisTitle(xColName).yAxisTitle("Y").build();
// Customize Chart
xyChart.getStyler().setLegendPosition(LegendPosition.InsideNE);
xyChart.getStyler().setAxisTitlesVisible(true);
xyChart.getStyler().setDefaultSeriesRenderStyle(XYSeriesRenderStyle.Line);
double[] yCoordArray = new double[xCoordArray.length];
// Loop through the series
for (int i = 0; i < yCoordinates.size(); i++) {
List<Double> yCoordOneSeries = yCoordinates.get(i);
// Convert list to array
for (int j = 0; j < yCoordArray.length; j++) {
yCoordArray[j] = yCoordOneSeries.get(j);
}
xyChart.addSeries(yColNames.get(i), xCoordArray, yCoordArray);
}
xyChartPanel = new XChartPanel<>(xyChart);
add(xyChartPanel, BorderLayout.CENTER);
xyChart.getStyler().setDefaultSeriesRenderStyle(XYSeriesRenderStyle.Area);
add(xyChartPanel, BorderLayout.CENTER);
}
Now the problem comes, I don't want my chart to be unchanged all the time, actually I want to change the style of my chart responded to my action on the radio buttons.
I just wrote the updateChartPanelStyle(JRadioButton styleButton) method that takes
private void updateChartPanelStyle(JRadioButton styleButton) {
String style = styleButton.getText();
if (styleButton.isSelected()) {
System.out.println(style);
switch (style) {
case "Line":
xyChart.getStyler().setDefaultSeriesRenderStyle(XYSeriesRenderStyle.Line);
break;
case "Area":
xyChart.getStyler().setDefaultSeriesRenderStyle(XYSeriesRenderStyle.Area);
break;
case "Scatter":
xyChart.getStyler().setDefaultSeriesRenderStyle(XYSeriesRenderStyle.Scatter);
}
xyChartPanel = new XChartPanel<>(xyChart);
add(xyChartPanel, BorderLayout.CENTER);
}
}
See in this method, I changed the style of xyChart I initialized in the last function, and reinitialize the xyChartPanel, then add the updated xyChartPanel to the working panel. Interestingly, I didn't see any change in my GUI. I thought this might be a problem with my xyChart whose style could not be changed afterward. But this is not really the case.
Even if I "removed" xyChartPanel with this.remove(xyChartPanel);, the GUI doesn't seems to be changed.
This is really weird, what should I do now?
Every time you add/remove components to swing dynamically, you need to call revalidate(); and then repaint(); on your JPanel (or JFrame if you're adding it straight to that).
I am a little new to swing. In order to learn to use the API correctly, I am designing the following project:
The project is a solving block puzzle solver sliding block puzzle similar to the rush-hour puzzles common in toy stores - https://en.wikipedia.org/wiki/Rush_Hour_(board_game) except there is no escape for a special car.
By dragging the blocks from an off board area to the board, the user specifies the starting configuration of the puzzle. The user, in the same way, specifies an ending goal configuration which dictates where some (or all) of the blocks the user specified initially must be at the end of the puzzle - the ending configuration can be specified using only SOME of the blocks, making multiple legal ending configurations.
The algorithm for solving the puzzle is already complete - I just need to design the interface and I am getting stuck. For designing the tray, I used a grid layout. Since blocks need to be entered at certain positions, I need to be able to place blocks in specific cells in the grid and move them around.
A 'block' object has four attributes - its height, width, its top row, and its left most column (ie - each block is addressed by its top left corner).
I used the suggestion here ( https://stackoverflow.com/questions/2510159/can-i-add-a-component-to-a-specific-grid-cell-when-a-gridlayout-is-used ) for the grid layout.
Right now I have only programmed to the point where java reads the puzzle from a .txt file and is supposed to display it on the screen ( I have not designed any user interactablity yet ).
First, here is the code I have written so far.
public class SolverPuzzleGUI extends JFrame {
//Specs from the puzzle.
Board initBoard;
ArrayList<Block> goalBlocks;
LinkedList<Move> moveList;
JLayeredPane layeredpane;
JPanel Board;
Dimension boardsize = new Dimension(400, 500);
JPanel[][] panelHolder = new JPanel[5][4];
public SolverPuzzleGUI(Board startBoard, ArrayList<Block> startGoalBlocks,
LinkedList<Move> startMoveList) {
this.initBoard = startBoard;
this.goalBlocks = startGoalBlocks;
this.moveList = startMoveList;
} // end constructor.
//gives the actual simulation
public void runSimulation() {
// Initalizing the main window.
setSize(500, 600);
setName("Solution");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setMinimumSize(getMinimumSize());
//Using layered pane
layeredpane = new JLayeredPane();
add(layeredpane);
layeredpane.setPreferredSize(boardsize);
layeredpane.setBackground(Color.YELLOW);
layeredpane.setVisible(true);
// adding the game tray
Board = new JPanel();
layeredpane.add(Board, JLayeredPane.DEFAULT_LAYER);
Board.setLayout(new GridLayout(5, 4));
// centering the game tray.
Board.setPreferredSize(boardsize);
Board.setMinimumSize(boardsize);
Board.setMaximumSize(boardsize);
Box box = new Box(BoxLayout.Y_AXIS);
box.add(Box.createVerticalGlue());
box.add(Board);
box.add(Box.createVerticalGlue());
add(box);
//Adding placeholders to the board for creating blocks
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 4; j++) {
panelHolder[i][j] = new JPanel();
panelHolder[i][j].setBackground(Color.DARK_GRAY);
Board.add(panelHolder[i][j]);
layeredpane.setLayer(panelHolder[i][j], JLayeredPane.DEFAULT_LAYER);
panelHolder[i][j].setVisible(false);
} // end 'j' for
} // end 'i' for
ArrayList<Block> initBlocks = initBoard.getBlocks();
//int count = 0; //DEBUG
for (Block block : initBlocks) {
this.drawBlock(block);
//count++;
//if(count > 4) { break; }
} // end 'for'
Board.setBackground(Color.DARK_GRAY);
Board.setVisible(true);
setVisible(true);
} // end 'run'
private void drawBlock(Block block) {
Dimension blockSize = new Dimension(block.getWidth()*100, block.getHeight()*100);
System.out.println(blockSize.width);
System.out.println(blockSize.height);
JPanel screenBlock = new JPanel();
screenBlock.setPreferredSize(blockSize);
screenBlock.setMinimumSize(blockSize);
screenBlock.setMaximumSize(blockSize);
screenBlock.setSize(blockSize);
screenBlock.setBackground(Color.BLUE);
screenBlock.setBorder(BorderFactory.createLineBorder(Color.BLACK));
layeredpane.setLayer(screenBlock, JLayeredPane.MODAL_LAYER);
int leftRow = block.getRow();
int leftCol = block.getColumn();
panelHolder[leftRow][leftCol].setSize(blockSize);
panelHolder[leftRow][leftCol].setVisible(true);
panelHolder[leftRow][leftCol].add(screenBlock);
layeredpane.setLayer(panelHolder[leftRow][leftCol], JLayeredPane.MODAL_LAYER);
screenBlock.setVisible(true);
}// end 'drawBlock'
public static void main(String[] args) {
String file = "C:\\Users\\Tim\\Desktop\\init.from.handout.txt";
String goal = "C:\\Users\\Tim\\Desktop\\goal.2.from.handout.txt";
/*
A SolverPuzzle object is the object which actually solves the algorithm -
when the class is constructed, it takes the file path of the inital
configuration as an input, as well as the file path of the goal
configuration. It has the following fields:
A 'board' object which specifies the inital configuration of the board.
It contains an ArrayList of Block objects(Remember block objects store
the height and width of the block, as well as the address of the
top left corner of block) which specify the starting
blocks, an ArrayList of EmptySpace objects which specify the empty
spaces on the board, an ArrayList of Move objects, which contain
the legal moves of the configuration, and the height and width of
the tray (in this application, the tray will always be 5 x 4).
An ArrayList of Block objects which specify the ending configuration.
A LinkedList of Move objects which specify the shortest possible
list of Moves which brings the configuration to a position which
satisfies the goal position. A Move object has three fields -
The block object being moved, and the row and column of the
top left corner of the block in the new position.
*/
SolverPuzzle test;
try { test = new SolverPuzzle(file, goal); }
catch (IOException ex) {
System.out.println("IOException");
return;
}
Board testBoard = test.getStartBoard();
ArrayList<Block> testGoalBlocks = test.getGoalBlocks();
LinkedList<Move> testMoveSolution = test.getMoveList();
// testing the gui
SolverPuzzleGUI testGUI = new SolverPuzzleGUI(testBoard, testGoalBlocks,
testMoveSolution);
testGUI.runSimulation();
}
} // end class 'SolverPuzzleGUI'
Here's the current output vs desired output.
http://imgur.com/a/ykXXP
So specifically, I have two questions:
1 - Why is the image only showing the top left corners of the blocks instead of the whole block?
2 - Is it better to continue using the GridLayout or switch to GridBagLayout?
Thanks
GridBagLayout would definitely be suitable for want you want to do. For example, you can expand components to envelop more than one column or row - just like what you want to do. Check out the java tutorials for how to use them.
A key point to remember when using GridBagLayoutis that you need to reset the Constraints after each component, assuming that they're unique to that particular component.
Also - I can't discern what you mean by only showing the top-left - it looks likes its showing the whole thing to me...
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();
}
}