Add panel to a panel - java

i'm building a Java program. The core of this program is visualized in a JFrame with a JMenuBar and various JMenuItem and JMenu. The point is that I added a centralPanel to all the frame,but if I add something to the centralPanel it shows only if i resize the main frame, reducing it or enlarging it!
Here's the code:
This is the constructor:
public UserFrame(Sistema system)
{
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setSize(screenSize.width, screenSize.height);
storicoPanel = new JPanel();
carrelloPanel = new JPanel();
carrelloFrame = new JFrame();
pane = new JScrollPane(storicoArea);
close = new JButton("Chiudi");
this.sistema = system;
menu = new JMenuBar();
this.setJMenuBar(menu);
centralPanel = new JPanel();
add(centralPanel);
Here i added the centralPanel, and here, in an ActionListener, i try to add something to it, but it doesnt' work:
public ActionListener createVisualizzaStorico(final ArrayList<Acquisto> array)
{
class Visualize implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
storicoPanel.removeAll();
for(Acquisto a : array)
{
Articolo temp = a.getArticolo();
if(temp instanceof Vacanza)
storicoPanel.add(new VacanzaPanel((Vacanza)temp));
else if(temp instanceof BeneDiConsumo)
storicoPanel.add(new BeneDiConsumoPanel((BeneDiConsumo)temp));
else if(temp instanceof Cena)
storicoPanel.add(new CenaPanel((Cena)temp));
else
storicoPanel.add(new PrestazioniOperaPanel((PrestazioneOpera)temp));
}
centralPanel.add(storicoPanel);
centralPanel.repaint();
Could you please help me? Thanks!

Use a CardLayout instead of trying to add and remove component/panels. It's much cleaner and you don't have to worry about the things that may go wrong, like what you're facing here.
See this example to see how easy and cleaner it is. Also see How to Use CardLayout tutorial
Side Notes
A component can only have one parent container. Though I don't think this is causing a problem for you. It's good to know. First I see you trying to add storicoPanel to a JScrollPane, JScrollPane that you never add to the centerPanel. Then you later add the storicoPanel to the centerPanel. The JScrollPane will no longer be the parent after this.
I'm not sure what you're using this carrelloFrame = new JFrame(); for, but you're class is already a JFrame, why create another?
Just FYI, when adding components dynamically, you need to revalidate() and repaint(). Though, in your situation, I am totally against the adding and removing of components, because this looks like a perfect case for a CardLayout.

Try these..
centralPanel.updateUI(); // or
SwingUtilities.updateComponentTreeUI(getRootPane());
Execute your frame code in SwingUtilities.invokeLater()
Instead of repaint() call updateUI() or
SwingUtilities.updateComponentTreeUI(getRootPane()) to update the
user interface.

Related

JPanel(null) not displaying JLabels

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

ListSelectionListener not changing panel

I want a ListSelectionListener event to change a JPanel. I know it is getting fired properly because the print statement is working, however the panel does not change at all.
DefaultListModel leftList = new DefaultListModel();
JList order = new JList(leftList);
order.addListSelectionListener(this);
JPanel configPanel = new JPanel();
public void valueChanged(ListSelectionEvent e) {
if(e.getValueIsAdjusting()){
int index = order.getSelectedIndex();
System.out.println(leftList.getElementAt(index).toString());
configPanel.removeAll();
configPanel.repaint();
configPanel.add(new JLabel("nice"));
configPanel.repaint();
}
}
I threw in the second repaint simply because I was out of things to try, however it still did not work.
When you add components to a visible GUI the basic logic is:
panel.remove(...);
panel.add(...);
panel.revalidate();
panel.repaint();
Basically all components have a size of (0, 0) when they are created so there is nothing to paint. You need to invoke revalidate() so the layout manager can give the components a size and location on the panel.

Cardlayout With Jbutton Not Switching

Hello I am fairly new to java programming and I am currently trying to work on a small game with a GUI, Right now I am stuck at an issue where I can only use a normal button with a card layout, unfortunately I want to use my own icon with the button and to do this I need to use a JButton. but for some reason when i use a JButton it does not get switched with the panels. I'm just wondering what I am doing wrong. I am programming as an applet with a IDE called Ready To Program.
{
CardLayout PanelLayout = new CardLayout ();
JPanel AppPanel = new JPanel (); //Main App Panel using cardlayout
JPanel StartPanel = new JPanel (); //Start Menu Panel
JPanel GamePanel = new JPanel (); //Running Game Panel
JButton StartBtn = new JButton ();
public void init ()
{
StartBtn.setIcon(new ImageIcon ("StartIcon.png"));
StartBtn.setBorder(BorderFactory.createEmptyBorder());
StartBtn.setContentAreaFilled(true);
StartPanel.add (StartBtn);
AppPanel.setLayout (PanelLayout);
AppPanel.add (StartPanel, "1");
AppPanel.add (GamePanel, "2");
PanelLayout.show (AppPanel, "1");
setLayout (new BorderLayout ());
add ("Center", AppPanel);
}
public boolean action (Event e, Object o)
{
if (e.target == StartBtn)
{
PanelLayout.show (AppPanel, "2");
}
return true;
}
}
Frist of all variable names should NOT start with an upper case character. I have never seen a tutorial or answer in any forum that uses an upper case character, so don't make up your own conventions. Learn by example.
I can only use a normal button with a card layout, unfortunately I want to use my own icon with the button and to do this I need to use a JButton.
A JButton is a normal button. What other kind of button are you referring to? It doesn't matter whether the button has text or Icon or both, it is still a button.
The button in your code doesn't work because you didn't add and ActionListener to the button.
Read the section from the Swing tutorial on How to Use Button for more information and examples. The tutorial also has a section on How to Write ActionListeners.
Your code has an action(...) method. I don't know if that is generated by the IDE or not, but basically the code in that method would be the code in your ActionListener.
add ("Center", AppPanel);
That is not the proper form of the method to add a component to a panel. First all don't use hardcoded literal strings, use the variables provided by the API:
add (appPanel, BorderLayout.CENTER);

Java Swing JTabbedPane add JPanel to tab then modify it

I want to create a JTabbedPane, add a JPanel to everyone and then add something to the JPanel:
private void initTabbedPane(JTabbedPane tp)
{
System.out.println("FestplattenreinigerGraphicalUserInterface::initTabbedPane()");
// Init Tab-Names
Vector<String> tabNames = new Vector<String>();
tabNames.addElement("Startseite");
tabNames.addElement("Konfiguration");
tabNames.addElement("Hilfe");
// Init Tabs
tp = new JTabbedPane();
JPanel tmpPanel;
for(int i = 0; i < tabNames.size(); i++)
{
tmpPanel = new JPanel();
tp.addTab(tabNames.elementAt(i), tmpPanel);
}
tp.setFont(new Font("Calibri", Font.BOLD, 11));
initPanelsInTabbedPane(tp);
this.getContentPane().add(tp, BorderLayout.CENTER);
}
private void initPanelsInTabbedPane(JTabbedPane tp)
{
System.out.println("FestplattenreinigerGraphicalUserInterface::initPanelsInTabbedPane()");
tp.getComponentAt(0).add(new JButton("HELLOSTUPIDJAVAIHATEU"));
}
Well it says:
incompatible types
found : java.awt.Component
required: javax.swing.JPanel
JPanel p = tp.getComponentAt(0);
But my book says that with, Component getComponentAt(int index), i can access it's content and i remember that JButton is a Component right? So wth?
If you take a look at Javadoc, you'll see that, indeed, JTabbedPane#getComponentAt(index) returns a Component. However, if you're sure it's a JPanel (which is more or less the case when accessing tabs of a JTabbedPane), you can always cast it :
((JPanel) tp.getComponentAt(0)).add(new JButton("come on, Java is nice enough, no ?"));
Or, even better if you know some things about Swing
((JCompoonent) tp.getComponentAt(0)).add(new JButton("No, Java and Swing positively rock hard awesome !"));
indeed, JPanel is a subclass of JComponent, which is
the root class of all Swing components
an awt Container

JPanels, JFrames, and Windows, Oh my!

Simply stated, I am trying to make a game I am working on full-screen.
I have the following code I am trying to use:
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
if(!gs.isFullScreenSupported()) {
System.out.println("full-screen not supported");
}
Frame frame = new Frame(gs.getDefaultConfiguration());
Window win = new Window(frame);
try {
// Enter full-screen mode
gs.setFullScreenWindow(win);
win.validate();
}
Problem with this is that I am working within a class that extends JPanel, and while I have a variable of type Frame, I have none of type Window within the class.
My understanding of JPanel is that it is a Window of sorts, but I cannot pass 'this' into gs.setFullScreenWindow(Window win)... How should I go about doing this?
Is there any easy way of calling that, or a similar method, using a JPanel?
Is there a way I can get something of type Window from my JPanel?
-
EDIT: The following method changes the state of JFrame and is called every 10ms:
public void paintScreen()
{
Graphics g;
try{
g = this.getGraphics(); //get Panel's graphic context
if(g == null)
{
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setExtendedState(frame.getExtendedState()|JFrame.MAXIMIZED_BOTH);
frame.add(this);
frame.pack();
frame.setResizable(false);
frame.setTitle("Game Window");
frame.setVisible(true);
}
if((g != null) && (dbImage != null))
{
g.drawImage(dbImage, 0, 0, null);
}
Toolkit.getDefaultToolkit().sync(); //sync the display on some systems
g.dispose();
}
catch (Exception e)
{
if(blockError)
{
blockError = false;
}
else
{
System.out.println("Graphics context error: " + e);
}
}
}
I anticipate that there may be a few redundancies or unnecessary calls after the if(g==null) statement (all the frame.somethingOrOther()s), any cleanup advice would be appreciated...
Also, the block error is what it seems. I am ignoring an error. The error only occurs once, and this works fine when setup to ignore the first instance of the error... For anyone interested I can post additional info there if anyone wants to see if that block can be removed, but i'm not concerned... I might look into it later.
Have you made any progress on this problem? It might be helpful if you could update your question with your expected behavior and what the code is actually doing? As was already pointed out, JFrame is a subclass of Window, so if you have a JFrame, you don't need a Window.
For what it's worth, I have a Java app which works in fullscreen mode. Although the screen is not repainted as often as yours, it is repainted regularly. I do the following to enter fullscreen:
// pseudo-code; not compilable
JPanel container = new JPanel();
container.setOpaque( true ); // make sure the container will be visible
JFrame frame = new JFrame();
frame.getContentPane().add(container); // add the container to the frame
frame. ... //other initialization stuff, like default close operation, maximize, etc
if ( fullScreenModeIsSupported )
frame.setUndecorated( true ); // remove window decorations from the frame
gs.setFullScreenWindow( frame );
frame.validate();
Then whenever I need to update the screen, I just plug a new JPanel into the container JPanel:
// pseudo-code; not compilable
container.removeAll(); // clean out the container
container.add( jPanelWithNewDisplay ); // add the new display components to the container
container.validate(); // update and redisplay
container.repaint();
Can't claim that it's technically perfect, but it works well for me. If the pseudo-code examples don't cut it, I can spend some time putting together a compilable example.
JPanel is not a subclass of Window. JFrame is.
So you could try:
JFrame yourFrame = new JFrame();
yourFrame.add(yourPanel);
appyYourFullScreenCodeFor( yourFrame );
That should work.
I think I got what you need.
Set the frame undecorated, so it
comes without any title bar and
stuff.
Add your panel to the frame., so it
looks like only your panel is shown.
Maximize your frame. So now it
should look like there's only your
panel taking the full screen without
and window stuff.
frame.setUndecorated(true);
frame.add(panel); //now maximize your
frame.
Note: Its important to note that the undecorated API can only be called when your frame is undisplayable, so if its already show, then first you need to do setVisible(false).
EDIT1: If all you want is to get the window containing your panel, then you can do this:
Window win = SwingUtilities.getAncestorOfClass(Window.class, myPanel);
Once you get the window instance you can pass it wherever you want.
EDIT2: Also the Frame class extends Window so you can directly do gs.setFullScreen(frame). You dont need to create a new window for that frame.
My understanding of JPanel is that it
is a Window of sorts
Why would you think that? Did you read the API? Does JPanel extend from Window?
You can try using the SwingUtilities class. It has a method that returns the Window for a given component.

Categories

Resources