I want to have a frame that it has 9 planes with red and blue and green color and I set the frame as a borderlayout manager but it doesn't show anything.please help me.thanks
(the LightsNPlanesApp is correct and can be run correctly but the MainFrame is not correct because it doesn't show anything)
The MainFrame:(just the main method)
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
MainFrame frame = new MainFrame();
addComponentsToPane(frame.getContentPane());
frame.pack();
frame.setVisible(true);
}
private void addComponentsToPane(Container pane) {
pane.add(new LightsNPlanesApp(), BorderLayout.PAGE_START);
pane.add(new LightsNPlanesApp(), BorderLayout.CENTER);
pane.add(new LightsNPlanesApp(), BorderLayout.PAGE_END);
}
});
}
add("Center", canvas3D);
... is obsolete / wrong and should be replaced with:
add(canvas3D, BorderLayout.CENTER);
How does the code you posted compile? Did you bother to listen to my suggestion about starting with simple code? Is the problem with your custom JPanel or all JPanel'?
Why don't you try adding 3 JPanels each with a different background color and see if that works first. Of course if won't work, but once you figure out that problem, then maybe you can use the same solution on your other class.
Of course because you haven't posted a proper SSCCE, I'm just guessing which is why I'm not giving your what I think the solution is outright. If you are going to make use guess what the code thats causing the problem is like, then you will need to guess the solution as well given the hints provided. And again a SSCCE does not mean you include the full code from your custom panel, it means you post simple code that simulates the problem.
Related
I just wrote a simple code where I want a canvas to appear in the CENTER of a JFrame and a config panel to appear in the NORTH of the same JFrame.However after adding them both the 'canvas' doesn't get displayed at all.If I only add the canvas it does get displayed but as soon as I add the config panel it doesn't get displayed anymore.
Furthermore if I try to add something else in the SOUTH of the same JFrame I get a illegal component position error no matter what..
I'm a complete noob when it comes to Swing so sorry if the answer is obvious but I tried googling and researching this for the last few hours without any luck.
Here's what I tried:
public class MainFrame extends JFrame {
ConfigPanel configPanel;
ControlPanel controlPanel;
DrawingPanel canvas;
public MainFrame() {
super("My Drawing Application");
init();
}
private void init() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
canvas = new DrawingPanel(this);
configPanel = new ConfigPanel(this);
controlPanel=new ControlPanel(this);
add(canvas,CENTER);
add(configPanel,NORTH);
add(controlPanel,SOUTH); //this gives me a illegal component position error
pack();
}
}
add(controlPanel,SOUTH);
All the lines should have errors. I'm not sure why that is the only one highlighted. The code should be:
add(controlPanel, BorderLayout.SOUTH);
The preferred constraint is to use: BorderLayout.PAGE_END. Read the section from the Swing tutorial on How to Use BorderLayout for more information and working examples.
Also, there is no reason to pass the frame to the panel in the constructor. If for some reason you need to know the frame of the panel you can invoke the SwingUtiltites.windowForComponent(…) method after the frame is visible.
please try getContentPane().add(controlPanel, SOUTH); instead of add(controlPanel, SOUTH);
do that for every component in the code you provided...
I have the following code where I try to place a JLabel in a custom location on a JFrame.
public class GUI extends JFrame
{
/**
*
* #param args
*/
public static void main(String args[])
{
new GUI();
}
/**
*
*/
public GUI()
{
JLabel addLbl = new JLabel("Add: ");
add(addLbl);
addLbl.setLocation(200, 300);
this.setSize(400, 400);
// pack();
setVisible(true);
}
}
It doesn't seem to be moving to where I want it.
The problem is that the LayoutManager of the panel is setting the location of the label for you.
What you need to do is set the layout to null:
public GUI() {
setLayout(null);
}
This will make it so the frame does not try to layout the components by itself.
Then call setBounds(Rectangle) on the label. Like so:
addLbl.setBounds(new Rectangle(new Point(200, 300), addLbl.getPreferredSize()));
This should place the component where you want it.
However, if you don't have a really great reason to lay out the components by yourself, it's usually a better idea to use LayoutManagers to work in your favor.
Here is a great tutorial on getting started with using LayoutManagers.
If you must go without a LayoutManager here is a good tutorial for going without one.
You put the location code under the frame and it will work but if you want it to work for sure
put the location code in a run while loop. That's what I did to figure it out and it works.
I am new to Java swing programming. I want to make a frame which will appear red and blue in turn one after another. So, I took 2 child JPanel, 1 for red and other for blue, and a for-loop. On each iteration I remove one panel from parent panel and add another. But, when I run the program it only shows the last state of the frame.
Can anyone explain why? And what's the intended approach to make a program work like that?
My code:
public class Test2 extends JFrame {
public Test2() {
JPanel Red = new JPanel(new BorderLayout());
JPanel Blue = new JPanel(new BorderLayout());
//...initialize Red and Blue
Red.setBackground(Color.red);
Blue.setBackground(Color.blue);
Red.setPreferredSize(new Dimension(200,200));
Blue.setPreferredSize(new Dimension(200,200));
JPanel panel = new JPanel(new BorderLayout());
panel.setPreferredSize(new Dimension(200,200));
add(panel);
pack();
setTitle("Border Example");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
int M = 1000000; //note that, I made a long iteration to not finish the program fast and visualize the effect
for(int i=0;i<M;i++)
{
if(i%(M/10)==0) System.out.println(i); //to detect whether the program is running
if(i%2==0)
{
panel.removeAll();
panel.repaint();
panel.revalidate();
panel.add(Red,BorderLayout.CENTER);
}
else
{
panel.removeAll();
panel.repaint();
panel.revalidate();
panel.add(Blue,BorderLayout.CENTER);
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Test2 ex = new Test2();
ex.setVisible(true);
}
});
}}
Don't use a loop. Swing will only repaint the frame once the entire loop has finished executing.
Instead you need to use a Swing Timer. When the Timer fires you invoke your logic. Read the section from the Swing tutorial on How to Use Swing Timers.
Here is a simple example of a Timer that simply displays the time every second: Update a Label with a Swing Timer
Also, don't remove/add panels. Instead you can use a Card Layout and sway the visible panel. Again read the tutorial on How to Use CardLayout.
Basically you don't need to use a while (or any other) loop, Swing only paints once it has finished that loop then repaint the GUI.
As stated before by #camickr on his answer, you could try a Swing Timer; here's an example that does exactly what you want.
From your comment on another answer:
Could you please explain why "repaint" does not work in a loop? And why is the Timer working without a "repaint"?
Swing is smart enough to know it doesn't needs to repaint in a loop, instead it will repaint once it the loop finishes, if you read the tutorial on Swing Custom Paint on the step 3 it says:
"Swing is smart enough to take that information and repaint those sections of the screen all in one single paint operation. In other words, Swing will not repaint the component twice in a row, even if that is what the code appears to be doing."
And Timer will repaint it, because it's not running on the EDT but in it's own Thread
I would suggest to take in one step at a time.
First make it run without changing panels / colors.
Now it doesn't because this
public final void Test2() {
is a method (which is never used) and not a constructor.
Change to a constructor declaration like :
public Test2() {
to make the program do something. Then you can go to the next step.
Also use Java naming conventions (like blue instead of Blue).
Example:
public class JFrameTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
JButton button = new JButton("Hello!");
frame.getContentPane().add(button);
frame.getContentPane().add(button);
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
});
}
}
In the above example 'button' object is added only once even though there are no errors. The reason why I ask this is, I would like to add a same JPanel object on JFrame and on JDialog (on some table double click for edit/delete feature). I am able to solve it by having two JPanel objects but just wanted to know why it is not possible.
You can only add Swing components once in the Swing hierarchy as you already found out. This is documented in the 'Using top-level components tutorial'
Each GUI component can be contained only once. If a component is already in a container and you try to add it to another container, the component will be removed from the first container and then added to the second.
Not completely sure whether there were technical limitations that let to this decision, but I could imagine that for example the getParent method would give strange results if you were able to add the same component to two Containers
I just started using MigLayout for SWING in Java and I'm really liking it so far. The only thing, though, is that the dock parameters don't seem to work the way I thought they worked and I can't figure out what I'm doing wrong.
The problem is: I'm trying to add a JButton inside a JPanel and docking it to the right side using panel.add(button, "east");. While it actually makes it the rightmost component, it still only takes the same space as it would in a flowLayout. What I'd like it to do is stick to the right side of the panel.
Here's some compilable code that recreates the problem:
public class MigLayoutTest extends JFrame
{
public MigLayoutTest()
{
setSize(500,500);
JPanel panel = new JPanel(new MigLayout());
panel.setBackground(Color.YELLOW);
setContentPane(panel);
panel.setSize(500,500);
panel.add(new JButton("Dock east"), "east");
panel.add(new JButton("No dock"));
}
public static void main(String[] args)
{
JFrame frame = new MigLayoutTest();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Here's what the output looks like:
And here's where I'd want the "dock east" button:
If I'm using the parameters wrong, I'd like it if someone could tell me how I'm supposed to make my button dock to the right side of the panel.
Thanks!
You have to specify growth paarameters:
new MigLayout("", "[grow]", "[]")
Be careful though how you use it - it may not work the way you think it is. Here is a good read up on MigLayout features http://www.miglayout.com/QuickStart.pdf