I'm currently programming a Calendar in Java. The Calendar itself fills out perfectly fine with the Month and Year being displayed in JComboBoxes above the grid below it. The Grid itself is full of empty JLabels or JButtons (for the days of the month). The JComboBoxes are linked to ActionListeners, which detect the user changing information (confirmed by System.out.print statements). However, I cannot find a way to "redraw" the JPanel after this occurs. The method being called completely creates a new JPanel and adds in the new JLabels/JButtons, but nothing on the JFrame is updated after this happens. I have attempted using both the repaint and revalidate on the whole JPanel (which includes the JComboBoxes and the grid below it in a BorderLayout), the JPanel with only the grid, and the JFrame, but nothing happens. Does anyone have any ideas what is wrong?
// This code is within the build() method that builds the GUI.
// This method adds the centerPanel into the mainPanel
yearChoice.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
int i = yearChoice.getSelectedIndex();
if (i >= 0) {
yy = Integer.parseInt(yearChoice.getSelectedItem()
.toString());
//System.out.println("Year=" + yy);
compute();
}
}
});
private void compute(){
elements = new int[6][7];
// OMITTED is the code that determines whether a cell in the array should be an empty
// JLabel or a JButton. This code is based on the Calendar, and does work properly,
// but I can't figure out how to get the new Month/Year to show up on a new Panel
centerPanel = new JPanel(new GridLayout(7, 7));
JLabel sunday = new JLabel("S"),
monday = new JLabel("M"),
tuesday = new JLabel("T"),
wednesday = new JLabel("W"),
thursday = new JLabel("Th"),
friday = new JLabel("F"),
saturday = new JLabel("S");
centerPanel.add(sunday);
centerPanel.add(monday);
centerPanel.add(tuesday);
centerPanel.add(wednesday);
centerPanel.add(thursday);
centerPanel.add(friday);
centerPanel.add(saturday);
for(int i = 0; i < 6; i++){
for(int j = 0; j < 7; j++){
if(elements[i][j] == -1){
centerPanel.add(new JLabel(" "));
}else{
centerPanel.add(new JButton("" + elements[i][j]));
}
}
}
// Here is where I attempt to repaint the centerPanel for the JPanel, but it
// doesn't work
}
The method being called completely creates a new JPanel and adds in the
new JLabels/JButtons, but nothing on the JFrame is updated after this
happens. I have attempted using both the repaint and revalidate on the
whole JPanel (which includes the JComboBoxes and the grid below it in
a BorderLayout), the JPanel with only the grid, and the JFrame, but
nothing happens. Does anyone have any ideas what is wrong?
you call another JPanel for (re)validate & repaint
updates are out of visible rectangle on the screen, put JPanel to the JScrollPane
if updates are out of visible rectangle you can to call JFrame.pack(), but in this case JFrame will be changed its Dimension on the screen
The method being called completely creates a new JPanel and adds in
the new JLabels/JButtons, but nothing on the JFrame is updated after
this happens.
for why reason you re_create a JPanel, create that once time and to play with setVisible(false/true)
don't re_create a JPanel, put these (two or three JPanels) to the CardLayout, then any changes will be only switch betweens views
for better help sooner post an SSCCE, short, runnable, compilable
code example
Related
I have a problem with Java Swing, in particular with JLayeredPane.
I have a Deck manager which contains 4 JPanels in a JLayeredPane, but when i add an object to a Pane, then switch to another, the objects turns invisible at first, but when i pass with the mouse on, it returns visible even thoug i'm on a different Panel, here's the code:
deckSelector = new JLayeredPane();
Point origin = new Point(30, 0);
for (int i = 0; i < types.length; i++) {
Deck deck = new Deck(types[i], colors[i], origin);
deckSelector.add(deck, i);
decks[i] = deck;
}
to change
int j = 0;
boolean found = false;
for(int i=0; i<types.length; i++){
if(selectors[i].isSelected()){
deckSelector.setLayer(decks[i], 3);
found = true;
j=2;
} else
if(!selectors[i].isSelected()){
deckSelector.setLayer(decks[i], j);
if(found) j--;
else j++;
};
}
to add a card:
Card btnNewButton = new Card("Name Card");
add(btnNewButton);
I have a deck manager which is the main JLayerdPane, it has 4 decks overlayed, in which i can add cards, but when i switch from a deck to another, the card is still visible. Can anyone help me?
but when i pass with the mouse on
A mouseOver event is generate for the component. In the case of a JButton the border is changed, so the component needs to repaint itself. So that is why the component becomes visible.
The point of using a JLayeredPane is to see all the layers at the same time. Its just that some components will be stacked on top of others.
If you only want to see a single panel at a time, then you should be using a Card Layout. Then you can swap which panel is visible and any given time.
If you think you really need to use a JLayeredPane then try using setVisible(false) on the panel you don't want to see. This should prevent events from being passed to components on the panel in that layer.
I am adding JLabels from an Arraylist to a JPanel and they will only display if i set a layout on the panel but i want to set the location of the labels myself when i try panel = new JPanel(null); all labels are not displayed.
Frame:
public static void Frame(){
panel = new JPanel(null);
JFrame frame = new JFrame("New");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.pack();
frame.setSize(400,400);
frame.add(panel);
}
ArrayList iteration that adds labels to panel
private static void printArray() {
for(int i = 0; i < food.size(); i++){
component = new JLabel(new Food(food.get(i).getColor(),
food.get(i).getIconHeight(), food.get(i).getIconWidth(),
food.get(i).getLocationX(), food.get(i).getLocationY()));
panel.add(component);
component.setLocation(food.get(i).getLocationX(),
food.get(i).getLocationY());
}
}
I can see from Debug it is definitely getting the location information, so why is it not putting it in this location.
The reason to set layout as null is so i can update the position of the label so i can "move" it around with keyboard input
The first thing you need to do is understand what job the layout manager actually does, because if you're going to remove it, you're going to need to take over it's work.
Layout managers are responsible for determining both the size and position of the components. They do this through a variety of means, but can make use of the getPreferred/Minimum/MaximumSize methods of the components.
So this would suggest you need to make your own determinations about these values, for example...
component = new JLabel(new Food(food.get(i).getColor(),
food.get(i).getIconHeight(), food.get(i).getIconWidth(),
food.get(i).getLocationX(), food.get(i).getLocationY()));
component.setSize(component.getPreferredSize());
component.setLocation(food.get(i).getLocationX(), food.get(i).getLocationY());
I'd also recommend using the Key Bindings over KeyListener, it doesn't suffer from the same focus related issues
I'm Writing a game where there are a set of islands and there are 5 workers on each island when i left click on a worker a cursor appears on it and when i right click on somewhere in the island the selected worker moves there..i want a JPanel to show on the right side of the screen every time i left click on a worker.the panel will show the workers stats such as Health and carrying weight but the problem is i can't make the panel appear.this is the code where i left click on a worker:
if(SwingUtilities.isLeftMouseButton(e)){
if(canSelect){
for (int j = 0; j < countries.size(); j++) {
for (int i = 0; i < countries.elementAt(j).getMen().size(); i++) {
if(m==countries.elementAt(j).getMen().elementAt(i).getX() && n==countries.elementAt(j).getMen().elementAt(i).getY()) {
countries.elementAt(j).getMen().elementAt(i).setY(countries.elementAt(j).getMen().elementAt(i).getY()+1);
countries.elementAt(j).getMen().elementAt(i).setSelected(true);
getGraphics().drawImage(arrow.getImage(), (countries.elementAt(j).getMen().elementAt(i).getX()+mapX)*20+5,(countries.elementAt(j).getMen().elementAt(i).getY()+mapY)*20-12,null);
canSelect = false;
}
}
}
}
}
I tried the below code on a jbutton click within JFrame and it didn't worked as expected. (that is to dynamically creating a panel with 2 labels and show in a JFrame)
JPanel p = new JPanel();
p.setLayout(new GridLayout(2, 1));
p.add(new JLabel("Health : 90%"));
p.add(new JLabel("Carrying weight : 4 Kg"));
this.add(p); //JFrame
p.setSize(100, 50);
p.setLocation(100, 100);
p.setVisible(true);
But adding the code this.validate(); at the end of the above code, it worked fine.
if, is this your problem, then it may help you.
Reference Link
May be your JPanel is created by below your existing JPanel so it can't be seen. Place your new JPanel on your existing JPanel . Like this
JPanel nPanel = new JPanel();
nPanel.setBounds(x,y,w,h); //your desired location and size
mainPanel.add(nPanel);
nPanel.setVisible(false);
Your can make it visible again with your event
I am making a monopoly game in Java and for some reason I cant seem to get this JFrame popup to refresh. When I click the button, the popup will appear, but when I close it and click it again later on it the game, it continues to show the features of the 1st JFrame. I assume that a totally new JFrame is created every time you click the button, but I cant seem to refresh the content. How do I fix this?
final static JButton tradeButton = new JButton("Click to Trade Property");
tradeButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0){
final JPanel tradePanelcombo = new JPanel();
for(int x = 1; x< Player.Props.size(); x++)
{
if(x != Player.CurrentPlayer)
{
ArrayList<Property> props = Player.Props.get(x);
ArrayList<String> propnames = new ArrayList<String>();
for(Property prop : props)
{
propnames.add(prop.getName());
}
String[] strings = new String[propnames.size()];
for (int y = 0; y<propnames.size(); y++)
{
strings[y] = propnames.get(y);
}
JLabel confirmLabel = new JLabel("Player :" + x);
JComboBox petList = new JComboBox(strings);
petList.setPreferredSize(new Dimension(100, 150));
tradeFrame.add(confirmLabel);
tradePanelcombo.add(petList);
}
}
tradeFrame.add(tradePanelcombo, BorderLayout.PAGE_END);
tradeFrame.setPreferredSize(new Dimension(500,500));
tradeFrame.setResizable(true);
tradeFrame.pack();
tradeFrame.setVisible(true);
}
});
It appears to me that a new frame and components are created every time.
So, if the frame doesn't update, then I guess it would be because your Properties are not updated so the data added to the components doesn't change.
Edit:
You need to create a new JFrame every time, or you need to remove all the old components from the frame before adding the new components.
When you add a component to a BorderLayout, the previous component doesn't get removed. So you actually have two components in the container. When Swing paints components it actually paints the components in the reverse order that they where added to the container (this is how Z-Ordering works).
If you remove the setResizable() method, and then resize the frame I believe you should see the new components start to show given that they should increase in size as the frame size increases.
I wanna fix a 2D board for a game. I've already fixed other panels for the Gui and everything goes well. But the panel for the board cant be printed on the window. I'm a bit confused about it as i think i've followed the same ideas as for the others panels i need.
Here's what i've done:
EDIT:
what I'm trying to do is fix a board panel for the game according to the dimensions of the it,hold every square in an array in order to use it after wherever it;s needed. I draw each little square of it with the method draw and put it back to the panel. So, each square on the board is a panel. This is the idea. But as u can see. There are troubles/errors on it.
EDIT: code updated.
just found a part of the problem. i thought first that i had set background to squared, but i didnt. with this one it appears on the panel a wide black "column". Unfortunately,still none squares. :(
One More EDIT:
Also,i realized that draw method is never called. when i put the draw method in the following method i can see the squares but they remain small. I redefine them with setSize but still no change.
How can I use paint method to edit the panels properly???? As it is now it can't. Even it can't return an object(eg panel) as it's polymorphic void!
/**
*Method used to construct the square in the area of the
*gui's grid. In this stage a GUISquare array is being constructed,
* used in the whole game as
*a mean of changing a square graphical state.
*#param squares is the squares array from whom the gui grid will be
*constructed.
*#see getSquare about the correspondance beetween a squareModel and
* a GUISquare.
*/
private void initBoardPanel(SquareModel[][] squares){
BoardPanel.setLayout(new GridLayout(height ,width )); //set layout
SquareRenderer[][] Squares;
JPanel[][] grid;
Squares=new GUISquare[height][width()];
grid=new JPanel[height()][width()];
for (int i=0; i<height(); i++){
for (int j=0; j<width() ; j++){
SquareRenderer kou=new SquareRenderer(i,j);
kou.setSquare(myGame.getSquares()[i][j]);
//NOTE: THE FOLLOWING DRAW METHOD CANT BE CALLED!!!?
if (myGame.getSquares()[i][j] instanceof SimpleSq ){
kou .paintPanel(i,j,"");}
else if (myGame.getSquares()[i][j] instanceof ActionSq )
{ kou .paintPanel(i,j);
}
//JUST BECAUSE DRAW CANT BE CALLED I PUT ITS CODE HERE:
//JUST TO CHECK:
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
JLabel label1 = new JLabel("Move To "+myGame.getSquares()[i][j].getGoTo());
JLabel label2 = new JLabel(""+myGame.getSquares()[i][j].getSquare());
panel.setBackground(Color.ORANGE);
panel.add(label2, BorderLayout.NORTH);
panel.add(label1, BorderLayout.CENTER);
panel.setSize(250,250);
///////// <--until here ---paint method<---
kou.add(panel);
kou.setVisible(true);
kou.setBackground(Color.BLACK);
Squares[i][j]= kou;
BoardPanel.add(kou);
BoardPanel.setVisible(true);
BoardPanel.setBackground(Color.WHITE);
}
}
this.add(BoardPanel,BorderLayout.WEST);
// this.pack(); //sets appropriate size for frame
this.setVisible(true); //makes frame visible
}
IMPLEMENTED BY SQUARERENDERER:
/**
* Transformer for Snake/Ladder
* <br>This method is used to display a square on the screen.
*/
public void paintPanel(int i,int j) {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
JLabel label1 = new JLabel("Move To"+myGame.getSquares()[i][j].getGoTo());
JLabel label2 = new JLabel(""+myGame.getSquares()[i][j].getSquare());
JSeparator CellSeparator = new JSeparator(orientation);
panel.add(CellSeparator);
panel.setForeground(Color.ORANGE);
panel.add(label2, BorderLayout.NORTH);
panel.add(label1, BorderLayout.CENTER);
}
I see a couple things that are problematic:
When using a layout manager, you should avoid calling setSize. Most layout managers will simply override it. You should use setPreferredSize, setMinimumSize, and setMaximumSize instead, which provide hints to the layout manager.
It doesn't look like the draw method of SquareRenderer ever adds the panel you create to anything. You should either add panel to the SquareRenderer in the last line of draw or (better) add the sub-components directly to the SquareRenderer instead.