How to fix a JButton to not take up the whole JFrame - java

I am a beginner in coding and I am learning Java. I'm busy making a log in system, and I have made a JFrame, but when I add a JButton, it takes up the whole JFrame.
public class LogInSystem extends Application{
#Override
public void start(Stage primaryStage)
{
// Setting the JFrame
JFrame frame = new JFrame("Log in System");
frame.setSize(2000, 2000);
frame.setVisible(true);
// Setting the button
JPanel panel = new JPanel();
Button btn1 = new Button();
btn1.setText("1");
btn1.setBounds(50, 150, 100, 30);
frame.add(btn1);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}

It seems like you declare a panel and not adding button into it as well as not adding the panel to the frame. You can try to add your button into panel and panel into frame,
panel.add(btn1);
frame.add(panel);
You can also use some useful layout for a particular panel. For example, BoxLayout, GridLayout and etc. By default, everything is set to be FlowLayout.

Related

JFrame will not load new screen

I have a class that extends JFrame and works by adding in 2 panels with BoxLayout buttons, and one JTabbedPane in the center which displays graphs.
I want one of the buttons to remove all current components in the frame and add new ones.
Here are the methods used.
private void createAndShowGraphs() {
ImageIcon createImageIcon(lsuLettersPath); //simple png file to fill one tab
final JTabbedPane jtp = new JTabbedPane();
JLabel iconLabel = new JLabel();
iconLabel.setOpaque(true);
jtp.addTab(null, icon, iconLabel);
//Here is where the errors begin
JPanel menu = new JPanel();
menu.setLayout(new BoxLayout(menu, BoxLayout.Y_AXIS));
//I want this button to remove all components currently in the JFrame and replace them with new components specified in the createAndShowIntro() method
menu.add(new JButton(new AbstractAction("Intro Pane") {
public void actionPerformed(ActionEvent e) {
//I've also tried putting removeAll in the Intro method
removeAll();
createAndShowIntro();
}
}));
add(jtp, BorderLayout.CENTER);
add(menu, BorderLayout.WEST);
pack();
setVisible(true);
}
private void createAndShowIntro() {
System.out.println("Made it to Intro");
//all I want is a blank JLabel with the String "test" to show up
JPanel test = new JPanel();
test.setLayout(new BorderLayout());
JLabel label = new JLabel();
label.setText("test");
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setVerticalAlignment(SwingConstants.CENTER);
test.add(label);
add(test, BorderLayout.CENTER);
test.revalidate();
label.revalidate();
validate();
test.repaint();
label.repaint();
repaint();
pack();
setVisible(true);
}
When I call createAndShowGraphs() in main() and then hit the 'Intro' button, everything freezes and nothing is actually removed. I know it makes it the Intro method because of the "Made it to Intro" string output to the terminal.
I've tried all kinds of combinations of invalidate(), validate(), revalidate(), repaint() on the labels and on the frame itself. Really frustrated because I don't know how else I'm going to be able to display 3 different screens to switch back and forth between while only actually displaying one at a time.
Thanks for your time.

Problems with BorderLayout() in Java

I've tried a lot of different ways, but I will explain two and what was happening (no error messages or anything, just not showing up like they should or just not showing up at all):
First, I created a JPanel called layout and set it as a BorderLayout. Here is a snippet of how I made it look:
JPanel layout = new JPanel();
layout.setLayout(new BorderLayout());
colorChoice = new JLabel("Choose your color: ");
layout.add(colorChoice, BorderLayout.NORTH);
colorBox = new JComboBox(fireworkColors);
colorBox.addActionListener(this);
layout.add(colorBox, BorderLayout.NORTH);
In this scenario what happens is they don't show up at all. It just continues on with whatever else I added.
So then I just tried setLayout(new BorderLayout()); Here is a snippet of that code:
setLayout(new BorderLayout());
colorChoice = new JLabel("Choose your color: ");
add(colorChoice, BorderLayout.NORTH);
colorBox = new JComboBox(fireworkColors);
colorBox.addActionListener(this);
add(colorBox, BorderLayout.NORTH);
In this scenario they are added, however, the width takes up the entire width of the frame and the textfield (not shown in the snippet) takes up basically everything else.
Here is what I have tried:
setPreferredSize() & setSize()
Is there something else that I am missing? Thank you.
I also should note that this is a separate class and there is no main in this class. I only say this because I've extended JPanel instead of JFrame. I've seen some people extend JFrame and use JFrame, but I haven't tried it yet.
You created a JPanel, but didn't add it to any container. It won't be visible until it is added to something (a JFrame, or another panel that is in a frame somewhere up the hierarhcy)
You added two components to the same position in the BorderLayout. The last one added is the one that will occupy that position.
Update:
You do not need to extend JFrame. I never do, instead I always extend JPanel. This makes my custom components more flexible: they can be added in another panel, or they can be added to a frame.
So, to demonstrate the problem I will make an entire, small, program:
public class BadGui
{
public static void main(String[] argv)
{
final JFrame frame = new JFrame("Hello World");
final JPanel panel = new JPanel();
panel.add(new JLabel("Hello"), BorderLayout.NORTH);
panel.add(new JLabel("World"), BorderLayout.SOUTH);
frame.setVisible(true);
}
}
In this program I created a panel, but did not add it to anything so it never becomes visible.
In the next program I will fix it by adding the panel to the frame.
public class FixedGui
{
public static void main(String[] argv)
{
final JFrame frame = new JFrame("Hello World");
final JPanel panel = new JPanel();
panel.add(new JLabel("Hello"), BorderLayout.NORTH);
panel.add(new JLabel("World"), BorderLayout.SOUTH);
frame.getContentPane().add(panel);
frame.setVisible(true);
}
}
Note that in both of these, when I added something to the panel, I chose different layout parameters (one label I put in 'North' and the other in 'South').
Here is an example of a JPanel with a BorderLayout that adds a JPanel with a button and label to the "North"
public class Frames extends JFrame
{
public Frames()
{
JPanel homePanel = new JPanel(new BorderLayout());
JPanel northContainerPanel = new JPanel(new FlowLayout());
JButton yourBtn = new JButton("I Do Nothing");
JLabel yourLabel = new JLabel("I Say Stuff");
homePanel.add(northContainerPanel, BorderLayout.NORTH);
northContainerPanel.add(yourBtn);
northContainerPanel.add(yourLabel);
add(homePanel);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLocationRelativeTo(null);
setExtendedState(JFrame.MAXIMIZED_BOTH);
setTitle("Cool Stuff");
pack();
setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(Frames::new);
}
}
The below suggestion is assuming that your extending JFrame.
Testing
First of all, without seeing everything, theres always a numerous amount of things you can try.
First off, after you load everything, try adding this in (Again, assuming your extending JFrame:
revalidate();
repaint();
I add this into my own Swing projects all the time, as it refreshes and checks to see that everything is on the frame.
If that doesn't work, make sure that all your JComponent's are added to your JPanel, and ONLY your JPanel is on your JFrame. Your JFrame cannot sort everything out; the JPanel does that.
JPanel window = new JPanel();
JButton button = new JButton("Press me");
add(window);
window.add(button); // Notice how it's the JPanel that holds my components.
One thing though, you still add your JMenu's and what-not through your JFrame, not your JPanel.

JFrame setComponentZOrder() changes size of the objects

I'm trying to write an undecorated JFrame. I'm trying to put my button over my background label. However setting the button's Z order causes the button streches to size of jframe and neither setBounds() nor setSize() changes the situation. Here is my code:
import javax.swing.*;
public class MyApp {
public static void main(String[] args) {
JFrame mainFrame = new JFrame();
mainFrame.setBounds(0, 112, 100, 50);
mainFrame.setLayout(null);
mainFrame.setUndecorated(true);
JLabel lblBackground = new JLabel(new ImageIcon(JFrame.class.getResource("/res/green.png")));
lblBackground.setBounds(0, 0, 100, 50);
JButton btnStart = new JButton("");
btnStart.setBounds(5, 15, 10, 15);
mainFrame.add(lblBackground);
mainFrame.add(btnStart);
mainFrame.setComponentZOrder(btnStart, 0);
mainFrame.setComponentZOrder(btnStart, 1);
mainFrame.setVisible(true);
}
}
Thanks for replies.
Use a JLayeredPane for this.
You will need to create a new JLayeredPane:
JLayeredPane layered = new JLayeredPane();
Set your JFrame to use this as a content pane:
mainFrame.setContentPane(layered);
And add your components, in this format:
layered.add(Component c, int layerNumber);
Hope that works for you!
More on JLayeredPanes
Don't play with null layouts. Swing was designed to be used with layout managers
Add the button to the label. For example:
JLabel label = new JLabel(...);
label.setLayout( new FlowLayout() );
JButton button = new JButton(...);
label.add( button );
frame.add(label);
frame.pack();
frame.setVisible(true);
Now the frame should be the same size as your image. The button should be centered on the top of the image. If you want the button positioned somewhere else then use a different layout manager.

How to make JLabel consume space when not visible?

I have a program which creates 2 Panels and then places a label and two buttons in them. The label is set to invisible setVisible(false) and then the two buttons are added and the frame is packed. When i click the first button, the label is shown, setVisible(true), and the seccond one hides it again, setVisible(false). When i click each button, they move to fill the space of the label as it hides, and move again to get out of the way of the label as it is shown. I want to stop this from happening and have the buttons stay in the same place even when the label is hidden.
Here is the code:
public class MainFrame extends JFrame{
public JLabel statusLabel;
public JButton show;
public JButton hide;
public MainFrame(){
super("MagicLabel");
JPanel topPanel = new JPanel(); //Create Top Panel
statusLabel = new JLabel(""); //Init label
statusLabel.setVisible(false); //Hide label at startup
topPanel.setSize(400, 150); //Set the size of the panel, Doesn't work
topPanel.add(statusLabel); //Add label to panel
JPanel middlePanel = new JPanel(); //Create Middle Panel
show= new JButton("Show"); //Create show button
hide= new JButton("Hide"); //Create hide button
middlePanel.setSize(400, 50); //Set the size of the panel, Doesn't work
middlePanel.add(show); //Add show button
middlePanel.add(hide); //Add hide button
this.add(topPanel, "North"); //Add Top Panel to North
this.add(middlePanel, "Center"); //Add Middle Panel to Center
addActionListeners(); //void:adds action listeners to buttons
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBounds(100, 100, 512, 400);
this.setPreferredSize(new Dimension(400,200)); //Set size of frame, Does work
this.pack();
this.setVisible(true);
}
public void animateInstall(boolean var0){ //Void to show and hide label from action listeners
statusLabel.setVisible(var0);
sendWorkingMessage("Boo!");
}
public void sendWorkingMessage(String message){ //Void to set text of label
this.statusLabel.setForeground(new Color(225, 225, 0));
this.statusLabel.setText(message);
}
void addActionListeners(){
show.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
animateInstall(true);
}
});
hide.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
animateInstall(false);
}
});
}
this.setPreferredSize(new Dimension(400,200));
this.setMinimumSize(new Dimension(400,200));
So pack() cannot interfere.
Use CardLayout. Add the JLabel and empty JPanel. Instead of seting it visible/invisible swap the cards showing the JLabel or the JPanel when necesary.
Extending JFrame is not advisable, better extend JPanel put all your components inside and then add it to a JFrame
You need to learn how to use SwingUtilities.invokeLater(): See example how your should look like
You need to learn about Layout: Tutorial
Very dumb and easy approach in your code would be:
this.statusLabel.setForeground(bgColor); //background color
this.statusLabel.setText(" "); //some number of characters
By default for you frame you are using BorderLayout. You can try to have like:
this.add(topPanel, BorderLayout.NORTH); //Add Top Panel to North
this.add(middlePanel, BorderLayout.SOUTH); //Add Middle Panel to South
rather than at center.
Or you can create an intermediate container panel for these 2 panels, or consider other layout managers like BoxLayout, etc

Swing: Showing a transparent Panel hovering over another Panel

I want to show a textArea showing some text (will show log lines) , and have an animated gif hoovering above it. I tried the solution described here , but all I get is a grey screen. Hints?
public class TestLayeredPanes {
private JFrame frame = new JFrame();
private JLayeredPane lpane = new JLayeredPane();
public TestLayeredPanes() {
frame.setPreferredSize(new Dimension(600, 400));
frame.setLayout(new BorderLayout());
frame.add(lpane, BorderLayout.CENTER);
//Build the animated icon
JLabel buildingIcon = new JLabel();
buildingIcon.setIcon(new ImageIcon(this.getClass().getResource(
"/com/ct/tasks/cmviewer/gui/progress_bar.gif")));
JPanel iconPanel = new JPanel();
iconPanel.add(buildingIcon);
//Build the textArea
JTextArea textLog = new JTextArea("Say something");
JPanel textPanel = new JPanel();
textPanel.add(new JScrollPane(textLog));
//Add the panels to the layered pane
lpane.add(textPanel, 0);
lpane.add(iconPanel, 1);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new TestLayeredPanes();
}
}
Try putting your animated GIF on the glass pane of your root pane:
http://download.oracle.com/javase/tutorial/uiswing/components/rootpane.html
JXLayer make easier to do that. Look at JXLayer samples.
You also can take a look at code of XSwingX
Since you started with a working example, why did you remove lines of code from the example you copied?
Layered panes don't use a layout manager therefore the size of your components are (0, 0), so there is nothing to display. The setBounds(...) method in the example are there for a reason.

Categories