Create responsive User Interface in Java - java

What is the best way to create an User Interface that is responsive in Java?
For example, I want that buttons resize when I change the size of the window...

I'd suggest using miglayout, as it is a user friendly and powerful layout manager that makes development of responsive interfaces easy.
This minimal example produces a interface with a single button that automatically resizes to fill the size of the window.
JFrame frame = new JFrame("MigLayout");
frame.setLayout(new MigLayout("fill"));
frame.add(new JButton("Button"), "grow");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
Moreover the layour manager is grid based, easy to use and extremely customizable, so I'd recommend it for a wide range of situations.

Related

JFrame and JPanel sizing

I have a JFrame and a few JPanels that are displayed depending on where the user goes (to login, homepage etc), is there a way to set all JPanels to the same size without having to manually specify?
public mainApp() {
main = new JFrame("Application");
main.setSize(640, 480);
main.setVisible(true);
}
private JPanel loginScreen() {
login = new JPanel(null);
login.setSize(640, 480);
login.setVisible(true);
}
For example I have 5 different JPanels, and have to specify the size in each, is there a way to set a default size that is the same as the JFrame?
You have different valid options here. Knowing that you want to change from one view to another and keep the same size, it sounds like the best option would be to use a CardLayout allowing you to change between the different views without having to worry about repainting and revalidating stuff (this tutorial from Oracle helped me a lot back when I was learning to use this layout: Oracle - How to use CardLayout.
However, as usual with Swing/AWT this is not the only valid option. For example, you could also use the BorderLayout that is applied by default to the ContentPane from the JFrame and add the desired JPanel to the Center of that BorderLayout. However, you would have to manage the view-changing process in this case.

How to jump from a JFrame class after a specific time

I would like to go to jump from my progress bar (which is not an entirely progress just a gif) to another JFrame that would take me to the Login Frame after 5seconds but i don't want to use splash nor use buttons.
My Loading Frame source code :
public static void main(String[] args) {
JFrame frame = new JFrame("Loading");
frame.getContentPane().setBackground(Color.white);
ImageIcon loading = new ImageIcon("loading.gif");
frame.add(new JLabel("", loading, JLabel.CENTER));
frame.setSize(400,400); // dimensions of the gif.(800x600)
frame.setUndecorated(true); // removing the minimize and shit..
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
So basically after this code is executed for about 10 seconds it would jump to another class that contains another frame called login.java .
In general you can use a Swing Timer to schedule an event.
Read the section from the Swing tutorial on How to Use Swing Timers.
However, this is not the best solution!
i don't want to use splash
Why are you trying to reinvent the wheel? Use Swing the way it was designed to be used.
A splash screen is designed for this purpose and will initially load faster.
The splash screen can be configured to automatically close after the specified time.
Read the section from the Swing tutorial on How to Create a Splash Screen for a working example.

How to use JFrame properly?

So I started working on a project, and after some research of JFrame, I tried this to get my window for the project:
ImageIcon hello = new ImageIcon("C:\\Users\\JP\\Desktop\\hello.jpeg");
JFrame frame = new JFrame("Test");
frame.setSize(640,480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setBackground(Color.GREEN);
frame.setIconImage(hello.getImage());
The frame comes up in it's correct size, but does not display the icon or have the correct background color.
If you are looking to change the background of your frame, you should take a look at this Setting background color of JFrame, but either way I recommend you use the design tab of window builder, because that can make your life much easier, and such stuff can be manipulated easily. (How to open a Java form in design view?)

Is there a way I can swap JPanel classes into and out of a JFrame? [duplicate]

To put it simple, there's a simple java swing app that consists of JFrame with some components in it. One of the components is a JPanel that is meant to be replaced by another JPanel on user action.
So, what's the correct way of doing such a thing? I've tried
panel = new CustomJPanelWithComponentsOnIt();
parentFrameJPanelBelongsTo.pack();
but this won't work. What would you suggest?
Your use case, seems perfect for CardLayout.
In card layout you can add multiple panels in the same place, but then show or hide, one panel at a time.
1) Setting the first Panel:
JFrame frame=new JFrame();
frame.getContentPane().add(new JPanel());
2)Replacing the panel:
frame.getContentPane().removeAll();
frame.getContentPane().add(new JPanel());
Also notice that you must do this in the Event's Thread, to ensure this use the SwingUtilities.invokeLater or the SwingWorker
frame.setContentPane(newContents());
frame.revalidate(); // frame.pack() if you want to resize.
Remember, Java use 'copy reference by value' argument passing. So changing a variable wont change copies of the reference passed to other methods.
Also note JFrame is very confusing in the name of usability. Adding a component or setting a layout (usually) performs the operation on the content pane. Oddly enough, getting the layout really does give you the frame's layout manager.
Hope this piece of code give you an idea of changing jPanels inside a JFrame.
public class PanelTest extends JFrame {
Container contentPane;
public PanelTest() {
super("Changing JPanel inside a JFrame");
contentPane=getContentPane();
}
public void createChangePanel() {
contentPane.removeAll();
JPanel newPanel=new JPanel();
contentPane.add(newPanel);
System.out.println("new panel created");//for debugging purposes
validate();
setVisible(true);
}
}
On the user action:
// you have to do something along the lines of
myJFrame.getContentPane().removeAll()
myJFrame.getContentPane().invalidate()
myJFrame.getContentPane().add(newContentPanel)
myJFrame.getContentPane().revalidate()
Then you can resize your wndow as needed.
Game game = new Game();
getContentPane().removeAll();
setContentPane(game);
getContentPane().revalidate(); //IMPORTANT
getContentPane().repaint(); //IMPORTANT
It all depends on how its going to be used. If you will want to switch back and forth between these two panels then use a CardLayout. If you are only switching from the first to the second once and (and not going back) then I would use telcontars suggestion and just replace it. Though if the JPanel isn't the only thing in your frame I would use
remove(java.awt.Component) instead of removeAll.
If you are somewhere in between these two cases its basically a time-space tradeoff. The CardLayout will save you time but take up more memory by having to keep this whole other panel in memory at all times. But if you just replace the panel when needed and construct it on demand, you don't have to keep that meory around but it takes more time to switch.
Also you can try a JTabbedPane to use tabs instead (its even easier than CardLayout because it handles the showing/hiding automitically)
The other individuals answered the question. I want to suggest you use a JTabbedPane instead of replacing content. As a general rule, it is bad to have visual elements of your application disappear or be replaced by other content. Certainly there are exceptions to every rule, and only you and your user community can decide the best approach.
Problem: My component does not appear after I have added it to the container.
You need to invoke revalidate and repaint after adding a component before it will show up in your container.
Source: http://docs.oracle.com/javase/tutorial/uiswing/layout/problems.html
I was having exactly the same problem!! Increadible!! The solution I found was:
Adding all the components (JPanels) to the container;
Using the setVisible(false) method to all of them;
On user action, setting setVisible(true) to the panel I wanted to
show.
// Hiding all components (JPanels) added to a container (ex: another JPanel)
for (Component component : this.container.getComponents()) {
component.setVisible(false);
}
// Showing only the selected JPanel, the one user wants to see
panel.setVisible(true);
No revalidate(), no validate(), no CardLayout needed.
The layout.replace() answer only exists/works on the GroupLayout Manager.
Other LayoutManagers (CardLayout, BoxLayout etc) do NOT support this feature, but require you to first RemoveLayoutComponent( and then AddLayoutComponent( back again. :-) [Just setting the record straight]
I suggest you to add both panel at frame creation, then change the visible panel by calling setVisible(true/false) on both.
When calling setVisible, the parent will be notified and asked to repaint itself.
class Frame1 extends javax.swing.JFrame {
remove(previouspanel); //or getContentPane().removeAll();
add(newpanel); //or setContentPane(newpanel);
invalidate(); validate(); // or ((JComponent) getContentPane()).revalidate();
repaint(); //DO NOT FORGET REPAINT
}
Sometimes you can do the work without using the revalidation and sometimes without using the repaint.My advise use both.
Just call the method pack() after setting the ContentPane, (java 1.7, maybe older) like this:
JFrame frame = new JFrame();
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
....
frame.setContentPane(panel1);
frame.pack();
...
frame.setContentPane(panel2);
frame.pack();
...

Adding a component to a BorderLayout container without specifying position

I'm a novice Java programmer, and I'm trying to work out the behaviour of BorderLayout in a particular situation.
Say you have:
JFrame frame = new JFrame();
frame.add(new JLabel("Test"));
The defualt layout manager for JFrame is BorderLayout. According to the Java tutorial for BorderLayout, a position must always be specified, e.g. by:
frame.add(new JLabel("Test"),BorderLayout.CENTER);
So I'm confused by the fact that it is possible to add a component without specifying a position. If I modify the above code to be:
JFrame frame = new JFrame();
frame.add(new JLabel("Test"));
frame.add(new JLabel("Test 2"));
frame.add(new JLabel("Test 3",BorderLayout.NORTH);
I get Test 2 being displayed in the center left of the screen, and Test 3 being displayed in the top left of the screen.
Am I right in my understanding that, if no position is specified, BorderLayout will just default to BorderLayout.CENTER and, if so, can anyone show me where this is documented? I'm sure it must be documented somewhere, but I can't find it anywhere!
Thanks
http://download.oracle.com/javase/6/docs/api/java/awt/BorderLayout.html
"As a convenience, BorderLayout interprets the absence of a string specification the same as the constant CENTER"

Categories