I am writting a simple application which has a button that opens a new window then display a simple GUI/Text to acccept inputs from a user. but for some reason, I can get JLabel to be displayed on the new window. The application has following structure:
+mainFrame - JFrame
+newFrame - JFrame
-+newPanel - JPanel
----title - JLabel
----submitButton -JButton
...
Buttons and textfields all display fine, but Jlabels won't show up at all. I have tried using different layouts and all but I still can't get it shown. JLabels inside mainFrame tree, works fine.. so it seems like the problem is due to newFrame declaration or something, but then button should not be displayed either. Well, I am kindda lost and can someone suggest me what I should check?
Thanks : )
Make sure you do frame.pack() before you make it visible.
It can also help to set borders on different components (in different colours) for debugging just to see which components are/aren't turning out with size 0, in order to narrow down your problem. Logging, or breakpointing the component's setSize method, can help too.
Apart from that, maybe post some sample code? At the moment, you're question is fairly vague to answer.
Firstly, do you know about JDialog, and JOptionPane - these classes are often a better way of showing another popup window. It is quite rare to use 2 JFrames, (though sometimes a sensible thing to do).
Secondly have you done pack() and setVisible(true)?
The code below works fine for me. Either this breaks for you and it is something about your Java implementation, or you must be doing something different, in which case can you tell us what it is:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class JLabelShower {
public static void main(String [] args) {
JFrame mainFrame = new JFrame("main frame");
JButton popup = new JButton("start new frame");
mainFrame.getContentPane().add(popup);
mainFrame.pack();
mainFrame.setVisible(true);
popup.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFrame newFrame = new JFrame("new frame");
JPanel newPanel = new JPanel();
JLabel title = new JLabel("title");
newPanel.add(title);
newFrame.setContentPane(newPanel);
newFrame.pack();
newFrame.setVisible(true);
}
});
}
}
In case you are using the JLabel as a placeholder, i.e. initialize it with an empty string and set the text later:
Since the JLabel's size gets calculated when the panel gets layed out (i.e. early on) and is based on the contained text, you'll probably end up with a label thinking it has a preferred size of (0, 0).
In this case you should tell the label what size it should ask for by calling setPreferredSize with an appropriate value.
And another cause might be the layoutmanager you are using in the surrounding panel. Maybe you are adding the label and the button in the same place, e.g. BorderLayout.CENTER. That would explain why only one of the two gets displayed.
Set the opacity of the JLabel object to true using title.setOpaque(true) . It will paint every pixel within bound of the JLabel object. This solved my problem of same type.
Related
I am making simple login screen. I added two JLabel's in JFrame in my program and it's running successfully but the problem is that when I run the program I got blank screen and empty jframe, however I have added two jlabel's in that frame but it's not showing me any thing and then if I minimize the window and after some time if I open that window again then I can see those components.
Here is my code:
package javaapplication41;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.*;
public class JavaApplication41 {
JavaApplication41()
{
JFrame cpec=new JFrame();
cpec.setBounds(300,200,600,350);
cpec.setUndecorated(false);
cpec.setVisible(true);
cpec.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel l = new JLabel(new ImageIcon("C:\\Users\\MUHAMMAD SHAHAB\\Documents\\NetBeansProjects\\Real Estate\\src\\real\\estate\\file (2).jpg"));
l.setBounds(100,100,200,125);
//l.setLayout(null);
cpec.add(l);
JLabel kiq=new JLabel(new ImageIcon("C:\\Users\\MUHAMMAD SHAHAB\\Documents\\NetBeansProjects\\Real Estate\\src\\real\\estate\\bla.jpg"));
kiq.setBounds(100,100,100,100);
//kiq.setLayout(null);
l.add(kiq);
}
public static void main(String[] args) {
JavaApplication41 ne=new JavaApplication41();
}
}
I am getting this output when I run program:
and when I minimize this window and again open this, then I am getting the desired output here it is:
what am I doing wrong?
You have to put cpec.setVisible(true); after adding all the items in your jframe.I hope this will surely solve your problem
You have set the visibility of JFrame at a very early stage. At that time the JLabel was not added. When you minimized and resized your frame, it got rendered again resulting in showing your added components.
Remember to add components before setting the Frame's visibility( set visibility at last).
Also I would suggest you to use GUI threads when working on swing components. Refer to swing utilities here : https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
Lastly set the layout of JFrame to null as you are trying to add labels to specific coordinates with setBounds() method.
Default layout of jframe is BorderLayout, so if you want you can change layout by reference of java.awt.Container abstract class.
It is initialized by getContentPane() of javax.swing.JFrame class.
The components are added only through reference of java.awt.Container class.
java.awt.Container c=cpec.getContentPane();
c.setLayout(new FlowLayout(FlowLayout.LEFT));
c.add(l); //label will get added to JFrame instance that is referenced
//then define size and at last define visibility
cpec.setSize(500, 500);
cpec.setVisible(true);
Set the Layout manager of the container as null. By default it uses BorderLayout as its Layout manager. You just have to call the getContentPane() method using the reference of the JFrame, which returns a container reference. Example:
Container c = frame.getContentPane();
c.setLayout(null);
For more information you can go through my Website.
I recently started learning Java and aam writing a gui for a character creation sheet for personal use. I believe i have gotten all of the back end stuff working properly, but I can't test it outside of the console because I can't get the GUI to display anything other than a gray box.
I have a main class that creates the JFrame and calls the constructors for my other character classes to do all of the work, but for some reason, nothing shows up in the GUI. I'm not getting any errors or anything and I have spent several hours researching possible solutions to no avail.
My code:
The main method:
public static void main(String[] args) throws IOException
{
JFrame main = new JFrame();
JMenuBar menu = new MenuBar();
JPanel character = new CreatorGUI();
main.getContentPane().add(character);
main.add(menu);
main.setJMenuBar(menu);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setSize(10000, 10000);
main.pack();
main.setVisible(true);
}
The CreatorGUI:
public CreatorGUI() throws IOException
{
JPanel container = new JPanel();
JPanel stats = makeStats();
JPanel mods = makeMods();
JPanel character = makeChar();
container.add(mods);
container.add(stats);
container.add(character);
add(container);
}
I am trying to get the GUI working in its most basic form to make sure everything is working before I go back and refine the GUI, but I have hit a wall.
Any help is much appreciated!
main.getContentPane().add(character);
main.add(menu);
main.setJMenuBar(menu);
Using main.getContentPane().add(...) is the same as main.add(...). That is the component gets added to the content pane.
The default layout manager of a JFrame is a BorderLayout.
When you don't specify a constraint the component is added to the CENTER. However only a single component can be added to the CENTER so the "menu" is replacing the "character" panel.
Get rid of the main.add(menu) statement. It should only be added to the menubar so you only need to use the setJMenuBar(...) method.
The most suspect method call there is setSize which takes the pixel height and width. 10000 is probably too large as a width and a height and so you may only be seeing a portion of what you're trying to display. Changing it to something like 800 x 800 may allow you to see new things.
I am coding an intense game and have an important question. In this game, thanks to searching and finding the revalidate() method and the repaint() method I have managed to successfully remove a JPanel and place another JPanel in it's place.
However... this is where the problems begin. I am able to do this, but there are multiple (can range from 9 to 729) such JPanels that need to be changed. I am able to do this in the JFrame no problem... however the issue I am currently facing is that although one JPanel is replaced properly, when I do the next one it is also replaced properly. However, after multiple tests I found that when the JFrame is refreshed by dragging it off and back on screen or any other such change the older changed JPanels vanish.
Is there any way that I can make the newly added JPanel's permanently there rather than vanishing if and only if the JFrame is refreshed??
Here is the code:
int a = f%27;
int b = g%27;
int c = a%9;
int d = b%9;
winningletter.setFont(new Font("Times New Roman", Font.BOLD, 17));
miniwin.add(winningletter);
((JPanel)((JPanel)newDossier.Board.metametametaboard[f/27][g/27].getComponent((a/9)*3+b/9)).getComponent((c/3)*3+d/3)).removeAll();
((JPanel)((JPanel)newDossier.Board.metametametaboard[f/27][g/27].getComponent((a/9)*3+b/9)).getComponent((c/3)*3+d/3)).setLayout(new GridLayout(1,1));
((JPanel)((JPanel)newDossier.Board.metametametaboard[f/27][g/27].getComponent((a/9)*3+b/9)).getComponent((c/3)*3+d/3)).add(miniwin);
((JPanel)((JPanel)newDossier.Board.metametametaboard[f/27][g/27].getComponent((a/9)*3+b/9)).getComponent((c/3)*3+d/3)).repaint();
metametametaminiminiwincheck[f/3][g/3]=winningletter.getText();
boardChanger(f, g, 4);
WinChecker(s, f,g,3,4,metametametaminiminiwincheck,x);
You should be using CardLayout: The CardLayout class manages two or more components (usually JPanel instances) that share the same display space.
It enables you to flip between panels the pro way. Each JPanel has an ID and you can display it using it.
link:
http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html
Code:
//Where instance variables are declared:
JPanel cards;
final static String BUTTONPANEL = "BUTTONPANEL";
final static String TEXTPANEL = "TEXTPANEL";
//Where the components controlled by the CardLayout are initialized:
//Create the "cards".
JPanel card1 = new JPanel();
JPanel card2 = new JPanel();
//Create the panel that contains the "cards".
cards = new JPanel(new CardLayout());
cards.add(card1, BUTTONPANEL);
cards.add(card2, TEXTPANEL);
Calling the JPanel to display:
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, BUTTONPANEL);
I found that when the JFrame is refreshed by dragging it off and back
on screen or any other such change the older changed JPanels vanish
Emm... it seems naturally that UI repaint() method is being invoked authomatically after you re-size JFrame etc :)
thanks to searching and finding the revalidate() method and the
repaint() method I have managed to successfully remove a JPanel
It is quite strange you point your code strategy for the graphics2d only :S If you don't need to paint a new UI every time but keep them , as I could get it, inited in the heap not to re-init to set into your JPanel (?which is acting as a canvas)...
Actually, if you want all JPanel(s) be inited at the same time and just get them one by one by some event you can simply use some kind of storage as a Map or List etc, add them all (invisible) to your 'canvas' preferrably FlowLayout manager and make a needed one visible/invisible by an event for example...
Still the major task you trying to achieve is not pretty clear because you do accent Graphics2D so maybe you trying to achieve some another effect ? :S
P.S.
Anyway, it would be better you to show the problem code snippet because your current question contains too less information as for now...
EDIT
((JPanel)((JPanel)newDossier.Board.metametametaboard[f/27][g/27].getComponent((a/9)*3+b/9)).getComponent((c/3)*3+d/3)).removeAll();
((JPanel)((JPanel)newDossier.Board.metametametaboard[f/27][g/27].getComponent((a/9)*3+b/9)).getComponent((c/3)*3+d/3)).setLayout(new GridLayout(1,1));
((JPanel)((JPanel)newDossier.Board.metametametaboard[f/27][g/27].getComponent((a/9)*3+b/9)).getComponent((c/3)*3+d/3)).add(miniwin);
((JPanel)((JPanel)newDossier.Board.metametametaboard[f/27][g/27].getComponent((a/9)*3+b/9)).getComponent((c/3)*3+d/3)).repaint();
Ok... so that is how you add component to your canvas... As I can see, the array in Board is static object... I may suggest, you have more than one canvas object(s)? If yes, it is naturally the miniwin(s) vanish because static array cannot have shared access by two invokers at a time; so I may recommend not to use static field in your case... Please read The Java Language Specification for more detailed information
If you have additional question details please comment
Report if that was helpful
I think I solved my problem, but I don't know why it works this way, so I'm hoping someone can explain it to me so I don't do the same mistake again in the future.
Here's a quick example that is compilable of what I'm trying to do:
public class BoxLayoutTest extends JFrame
{
public BoxLayoutTest()
{
setSize(400,300);
JPanel mainPanel = new JPanel(new FlowLayout());
setContentPane(mainPanel);
JPanel subPanel = new JPanel();
subPanel.setLayout(new BoxLayout(subPanel, BoxLayout.PAGE_AXIS));
subPanel.setBackground(Color.BLUE);
JLabel labelTest = new JLabel("This is a test");
subPanel.add(labelTest);
labelTest.setPreferredSize(new Dimension(150, 20));
mainPanel.add(subPanel);
System.out.println(mainPanel.getSize());
}
public static void main( String[] args )
{
BoxLayoutTest testFrame = new BoxLayoutTest();
testFrame.setVisible(true);
}
}
At first, I had problems with the panel containing the JLabel not resizing like it should with the preferred size. I found out that it was because I was using some variation of mainPanel.getSize() as a preferred size for my subpanels. In this example, I'm using actual number values, which work.
The reason why it didn't work the old way (and that's actually the thing I'd like someone to explain), is why, as seen in the SOP line, mainPanel.getSize() returns a width and a height of 0 while it clearly takes the whole screen, which is 400x300.
Thanks #camickr for telling me I shouldn't set a preferredSize for my Panels, this helped me figure out where the problem was coming from.
Why [does] mainPanel.getSize() returns a width and a height of 0?
Until pack() "causes this Window to be sized to fit the preferred size and layouts of its subcomponents," the dimensions will be zero.
System.out.println(mainPanel.getSize());
this.pack();
System.out.println(mainPanel.getSize());
Console:
java.awt.Dimension[width=0,height=0]
java.awt.Dimension[width=160,height=30]
Its hard to say why your code doesn't work, since you didn't post your code. A few random lines of code does not give us the context of how the code is used in your program.
When you post a question you need to post your SSCCE which demonstrates the problem.
The glue should not have fixed the problem. The panel should still display, its just that it may not display in the position you expect it to be. A BoxLayout will attempt to resize components added to it to fill up the entire space available to it.
You should not be using setPreferredSize() on a panel. It is the job of the layout manager to calculate the preferred size of the panel based on the preferred size of all the components added to it. So I would say your code is still wrong.
is there a difference between typing this and this.getContentPane()
Certain methods calls are automatically forwarded to the content pane of the frame, which is why the end result is the same. Read the JFrame API. This is addressed in the API description or for the method in question.
I'm having trouble finding out why the following problem happens: In a program that uses "extends Frame" to create a window, I can use BufferedImage to draw to the graphics context of the Frame (not JFrame), and it looks just fine. However, the moment I declare a JPanel, all of the text drawn by BufferedImage becomes obscured (not completely, but semi-transparent and hard to read), even if I don't add the JPanel to the JFrame.
Here's a simplified version of the code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.Timer;
import java.awt.image.*;
import javax.swing.*;
public class MyProgram extends Frame {
static Frame f;
static Timer timer;
public static void main(String[] args) {
f = new Frame();
f.setSize(400, 200);
f.setResizable(false);
f.setVisible(true);
f.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
drawScreen();
}
});
drawScreen();
}
public static void drawScreen() {
BufferedImage off_i = new BufferedImage(f.getWidth(), f.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = off_i.createGraphics();
g.setColor(new Color(50, 50, 50));
g.drawString("Hit any key; why does this text change?", 15, f.getHeight() - 10);
Graphics off_g = f.getGraphics();
off_g.drawImage(off_i, 0, 0, null);
JPanel panel = new JPanel();
}
}
I could maybe understand seeing the problem arise if I had added the JPanel to the JFrame and didn't set any bounds to its visibility, but even creating the JPanel gives that issue, which seems weird to me.
Basically, what I'm trying to do here is take an existing program that I have that runs just fine without JPanel, and I want to add to it a JTextArea so that I can accept copy/paste text for modifying the displaying of the program.
My understanding of Java is kind of spotty, as I learned it mainly by hobby and not formally, but I'm always looking to learn more when I can. Thanks for the help!
Update: I discovered that this problem only happens when the draw function is called again, after the JPanel has been declared, though I still don't understand why it does that or how to get around it.
better would be put Image to the JLabel and how ot use Icon
please read Using Swing Components and how to LayoutManagers works
tons examples on java2s.com
Don't mix AWT components with Swing component. That is you should use a JFrame NOT a Frame.
Don't use getGraphics(). Custom Painting is done by overriding the paintComponent() method of a JPanel (or JComponent). You just use the Graphics object that is passed to the method. Then you add the panel to the frame.
As already mentioned using a JLabel is simpler because you don't have to do any custom painting. The tutorial also has a section on "How to Use Icons".
I tried to run your code. And although the effect that you are describing does not happen on my system I can recommend you something.
First try to create your panel before it is visualized. In this case java does not have to re-arrange the components that are already on screen.
Second, if you have to draw things on visible frame call validate() of the container when you are done. This makes java to re-arrange stuff.
Third, when you are using drawXXX() methods create your own class that extends Component, JComponent, Canvas and override its `paint(Graphics) method. In this case the system will call this method every time it needs (e.g. when window is resized) and your UI will be painted again.
BTW I have 2 questions:
why are you using drawText() instead
of Label or JLabel? Use them and
avoid such kind of problems.
Why do you extend your class from Frame and do not use this fact but create yet another instance of Frame?
As an answer to my original question:
It seems that initializing JPanel alongside awt draw() commands causes the text to be antialiased, which makes the text look harder to read, partially obscured, thinner, etc. Although I tried setRenderingHint() with VALUE_TEXT_ANTIALIAS_OFF, it did not solve the problem. But as other posters pointed out it's not best practice to mix the two components.
While this doesn't exactly solve my problem, it does answer the question of what is going on, that being text antialiasing as some result of JPanel (does that sound right?). Ideally I wouldn't want to rewrite all of the code just to add a single JTextArea into an already existing codebase. But perhaps it's good every now and then to revisit old code and revamp it where it may be faulty.
Thanks everyone for the comments, information, and resource links!