I am creating a GUI in java. Currently i have an empty JFrame and am trying to add a JPanel to it. The JPanel contains buttons, text etc. However none of this is being displayed. My code is as follows:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class memoDisplayUI {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JTextArea jTextBox = new JTextArea();
JScrollPane scroll = new JScrollPane();
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
memoDisplayUI frame = new memoDisplayUI();
frame.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public memoDisplayUI() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame.getContentPane().setBackground(new Color(255, 255, 255));
frame.getContentPane().setLayout(null);
frame.setBounds(100, 100, 270, 400);
frame.setUndecorated(true); //REMOVES MENU BAR
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lblMemos = new JLabel("MEMOS");
lblMemos.setForeground(new Color(100, 149, 237));
lblMemos.setFont(new Font("Moire", Font.BOLD, 30));
lblMemos.setBounds(16, 16, 234, 37);
panel.add(lblMemos);
JButton button = new JButton("");
button.setBackground(new Color(100, 149, 237));
button.setBounds(7, 350, 40, 40);
panel.add(button);
button.setIcon(new ImageIcon("back.png"));
JButton button_1 = new JButton("");
button_1.setBackground(new Color(100, 149, 237));
button_1.setBounds(113, 350, 40, 40);
panel.add(button_1);
button_1.setIcon(new ImageIcon("Edit.png"));
JButton button_2 = new JButton("");
button_2.setBackground(new Color(100, 149, 237));
button_2.setBounds(220, 350, 40, 40);
panel.add(button_2);
button_2.setIcon(new ImageIcon("memo.png"));
JButton btnExit = new JButton("");
btnExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
System.exit(0);
}
});
btnExit.setBorder(null);
btnExit.setIcon(new ImageIcon("Exit.jpg"));
btnExit.setBounds(216, 19, 40, 40);
panel.add(btnExit);
jTextBox = new JTextArea();
scroll.setViewportView(jTextBox); // add scroll panel
jTextBox.setTabSize(4);
jTextBox.setLineWrap(true);
jTextBox.setBackground(new Color(192, 192, 192));
jTextBox.setBounds(8, 60, 255, 286);
panel.add(jTextBox);
frame.getContentPane().add(panel);
}
}
Could someone please advise as to why this is?
Thanks very much :)
Edit
From a few tweaks to the code, it appears this is the desired layout (in a non-resizable GUI).
I think you used null to get a "place it wherever fits"? Then use a FlowLayout
frame.setLayout(new FlowLayout());
That should fix it :)
Could someone please advise as to why this is?
Using null layouts and not calling pack().
The image I edited into the question was obtained as a screenshot of the GUI after I had commented out the call to setUndecorated(true) and dragged it a little bigger. Doing so causes the JRE to validate the component structure (what pack() would do) and thereby make the components appear.
As I mentioned in a comment:
..a better question would be "How to layout this GUI?" (so long as you provide an attempt)
And that leads me to my first comment. (Now in longer form)
Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement of components. To organize the components for a robust GUI, instead use layout managers, or combinations of them1, along with layout padding & borders for white space2.
So coming back to:
(so long as you provide an attempt)
Look over those two examples to see how they work, then attempt to combine some layouts and padding to create a frame that can then be packed to reduce to the natural size.
And a tip the the JTextArea. Suggest a size in columns x rows combined with the Font size.
1: You should never call setLayout(null).
2: Try frame.validate() to layout the components with your layout.
Replace
frame.getContentPane().setLayout(null);
with
frame.getContentPane().setLayout(new BorderLayout());
Good luck.
Edit: For future reference, to decide which LayoutManager should be used in your case, you should refer to this Visual Guide to LayoutManagers.
Just remove/comment this line from the above code at line number 46.
// frame.getContentPane().setLayout(null);
It should work fine..
Maybe you shoul replace :
frame.getContentPane().add(panel);
by
frame.setContentPane(panel);
Hope it helped
Related
So i am trying to make a Menu for a game i am working on.
I want to put an image as background at my menuPanel but i cant figure out how to let the image rescale every time i am raising the window. I have made a JLabel and i have imported an image from my main method and when i launch the game i can see that the image is correctly imported but i want to fill up all menuPanel and also stretch as i am raising the window to full screen or decreasing to the Minimum size of my frame.
How can i do that?
As you can see at the screenshot i want the text to be on top of the image and the image as a background and full screen.
public class Window extends Canvas{
private static final long serialVersionUID = 6331412385749386309L;
private static final int WIDTH = 1024, HEIGHT = WIDTH / 16 * 9;
private JFrame frame;
private JPanel mainPanel;
private JPanel menuPanel;
private JPanel buttonsPanel;
private JPanel playPanel;
private JPanel optionsPanel;
private JButton playBtn;
private JButton optionsBtn;
private JButton quitBtn;
private int currWidth = WIDTH, currHeight = HEIGHT;
public Window(String title, Game game) {
frame = new JFrame(title);
frame.setSize(1024, 576);
frame.setMinimumSize(new Dimension(WIDTH, HEIGHT));
frame.requestFocus();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
frame.setLocationRelativeTo(null);
menu();
game.start();
}
private void menu() {
frame.getContentPane().setLayout(new BorderLayout(0, 0));
mainPanel = new JPanel();
mainPanel.setBackground(new Color(255, 255, 255));
frame.getContentPane().add(mainPanel);
mainPanel.setLayout(new CardLayout(0, 0));
// menuPanel config
menuPanel = new JPanel();
menuPanel.setForeground(new Color(0, 0, 0));
menuPanel.setBackground(new Color(0, 0, 0));
mainPanel.add(menuPanel, "menuPanel");
buttonsPanel = new JPanel();
buttonsPanel.setBorder(null);
buttonsPanel.setBackground(new Color(0, 0, 0));
// playBtn config
playBtn = new JButton("Play");
playBtn.setForeground(new Color(255, 255, 255));
playBtn.setFont(new Font("Segoe Script", Font.BOLD, 40));
playBtn.setOpaque(false);
playBtn.setContentAreaFilled(false);
playBtn.setBorderPainted(false);
playBtn.setFocusPainted(false);
// optionsBtn config
optionsBtn = new JButton("Options");
optionsBtn.setForeground(new Color(255, 255, 255));
optionsBtn.setFont(new Font("Segoe Script", Font.BOLD, 35));
optionsBtn.setOpaque(false);
optionsBtn.setContentAreaFilled(false);
optionsBtn.setBorderPainted(false);
optionsBtn.setFocusPainted(false);
//quitBtn config
quitBtn = new JButton("Quit");
quitBtn.setForeground(new Color(255, 255, 255));
quitBtn.setFont(new Font("Segoe Script", Font.BOLD, 35));
quitBtn.setOpaque(false);
quitBtn.setContentAreaFilled(false);
quitBtn.setBorderPainted(false);
quitBtn.setFocusPainted(false);
GroupLayout gl_buttonsPanel = new GroupLayout(buttonsPanel);
gl_buttonsPanel.setHorizontalGroup(
gl_buttonsPanel.createParallelGroup(Alignment.TRAILING)
.addGroup(gl_buttonsPanel.createSequentialGroup()
.addContainerGap()
.addGroup(gl_buttonsPanel.createParallelGroup(Alignment.LEADING)
.addComponent(quitBtn, GroupLayout.DEFAULT_SIZE, 175, Short.MAX_VALUE)
.addComponent(playBtn, GroupLayout.DEFAULT_SIZE, 175, Short.MAX_VALUE)
.addComponent(optionsBtn, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
gl_buttonsPanel.setVerticalGroup(
gl_buttonsPanel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_buttonsPanel.createSequentialGroup()
.addContainerGap()
.addComponent(playBtn)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(optionsBtn, GroupLayout.PREFERRED_SIZE, 74, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(quitBtn, GroupLayout.PREFERRED_SIZE, 71, GroupLayout.PREFERRED_SIZE)
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
buttonsPanel.setLayout(gl_buttonsPanel);
//
JLabel menuImageLabel = new JLabel(new ImageIcon(Game.menu_image.getScaledInstance(700, 400, Image.SCALE_FAST)));
//
GroupLayout gl_menuPanel = new GroupLayout(menuPanel);
gl_menuPanel.setHorizontalGroup(
gl_menuPanel.createParallelGroup(Alignment.TRAILING)
.addGroup(gl_menuPanel.createSequentialGroup()
.addComponent(menuImageLabel, GroupLayout.PREFERRED_SIZE, 762, GroupLayout.PREFERRED_SIZE)
.addGap(0)
.addComponent(buttonsPanel, GroupLayout.DEFAULT_SIZE, 195, Short.MAX_VALUE))
);
gl_menuPanel.setVerticalGroup(
gl_menuPanel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_menuPanel.createSequentialGroup()
.addGap(161)
.addComponent(buttonsPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(124))
.addComponent(menuImageLabel, GroupLayout.DEFAULT_SIZE, 537, Short.MAX_VALUE)
);
menuPanel.setLayout(gl_menuPanel);
// playPanel config
playPanel = new JPanel();
playPanel.setBackground(new Color(0, 0, 255));
mainPanel.add(playPanel, "playPanel");
// optionsPanel config
optionsPanel = new JPanel();
optionsPanel.setBackground(new Color(255, 0, 0));
mainPanel.add(optionsPanel, "optionsPanel");
frame.setVisible(true);
setActions();
}
private void setActions() {
// playBtn action
playBtn.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
playBtn.setForeground(new Color(200, 210, 10));
}
public void mouseExited(MouseEvent e) {
playBtn.setForeground(new Color(255, 255, 255));
}
public void mouseClicked(MouseEvent e) {
menuPanel.setVisible(false);
playPanel.setVisible(true);
optionsPanel.setVisible(false);
}
});
// optionsBtn action
optionsBtn.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
optionsBtn.setForeground(new Color(200, 210, 10));
}
public void mouseExited(MouseEvent e) {
optionsBtn.setForeground(new Color(255, 255, 255));
}
public void mouseClicked(MouseEvent e) {
menuPanel.setVisible(false);
playPanel.setVisible(false);
optionsPanel.setVisible(true);
}
});
// quitBtn action
quitBtn.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
quitBtn.setForeground(new Color(200, 210, 10));
}
public void mouseExited(MouseEvent e) {
quitBtn.setForeground(new Color(255, 255, 255));
}
public void mouseClicked(MouseEvent e) {
System.exit(0);
}
});
}
public void tick() {
mainPanel.getSize(new Dimension(currWidth, currHeight));
System.out.println(currWidth + ", " + currHeight);
}
public void render() {
}
}
Swing is based on parent/child relationships.
So if you want the button displayed on the background the structure of your code needs to be:
- frame
- background component
- buttons panel
The easiest way to do this is to use a JLabel with your image as the background. Then you add the buttons panel to the label. The only issue is that by default a JLabel doesn't use a layout manager so you need to see the layout manager to achieve your desired effect.
I would suggest using a GridBagLayout, then the buttons will be centered on the panel. The basic code would be:
JPanel buttons = new JPanel();
buttons.add(...);
JLabel background = new JLabel(...);
background.setLayout( new GridBagLayout() );
background.add(buttons, new GridBagConstraints());
The label will be displayed at the size of the background image.
If you want the background image to scale as the frame size changes, then you have a couple of options:
Use the Stretch Icon. It will automatically scale the image to the space available.
Replace the JLabel with a JPanel and paint the image yourself. Check out the Background Panel which can be configured to automatically scale an image.
Edit:
i tried reading the code and its really confusing.
Well, the intent was not for you to read the code. The intent was for you to use the code.
When you program you learn how to use classes and the methods of the class. When you use the ImageIcon class did you read the code first or just learn how to use its contructor?
Now I agree, the two classes don't have a published API but you really only need to understand the constructors and methods of the classes in order to use them.
If you read the Stretch Icon blog it states:
StretchIcon is a drop-in replacement for ImageIcon, which it extends, except that ImageIcon’s no-arg constructor isn’t supported.
So that means that if you would normally use:
JLabel background = new JLabel( new ImageIcon("background.jpg") );
you would use the following for the StretchIcon:
JLabel background = new JLabel( new StretchIcon("background.jpg") );
Similarly for the BackgroundPanel, if you read the blog it states that it is:
an extension of JPanel that provides some custom painting support for the drawing of images
It then goes on to say that the default is to paint the image "scaled" which is what you want. So all you need to figure out is which constuctor to use to create the panel.
For a regular panel you would use:
JPanel background = new JPanel();
For the BackgroundPanel the simplest constructor to use would be the first constructor of the class which simply takes an Image as a parameter:
JPanel background = new BackgroundPanel(image);
Now you have a panel and you simply add your 3 buttons to the panel.
I did not write the StretchIcon class so I don't know the details of the code, and I don't care about the details as long as the class does what I expect it to do.
I did write the BackgroundPanel class so if you has specific questions then I can probably help you. But I don't have time to guess which part of the code you find confusing.
Edit 2:
I have 3 buttons and i want them to be at the cemter and stretch too so they stay at the center of the image
This is about learning how to use layout managers. I never use an IDE to generate my code. I want full control over the code. This allows your code to be cleaner an more easily maintained.
This allows you to choose the appropriate layout manager for the job and allows you to easily nest panels with different layout mangers. In this case you want to use the GridBagLayout which by default will center horizontally and vertically any component added to it.
By default the BackgroundPanel uses a BorderLayout. But you can easily change it to use the GridBagLayout. Then I would use a second panel with a GridLayout for the buttons.
So the code would be something like:
JPanel buttonPanel = new JPanel( new GridLayout(0, 1, 10, 0) );
buttonPanel.add(playBtn);
...
backgroundPanel.add(buttonPanel, new GridBagConstraints());
Now as the frame size is changed the buttons will automatically re-center.
Read the section from the Swing tutorial on Layout Managers for more information and examples.
Keep a link to the Swing tutorial handy. It contains information and example of most Swing basics.
You could use the method paintComponent(Graphics g) and drawImage() from JPanel to draw your Image.
import java.awt.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class AutoScale extends JFrame{
private Image image;
public AutoScale() {
setTitle("AutoScale");
setResizable(true);
setSize(400,400);
try {
image = ImageIO.read(new File("path to your file"));
}catch(IOException e) {
System.out.println("Image not found");
}
JPanel panelImg = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 30, 30, getWidth()/2, getHeight()/2, null);
}
};
add(panelImg);
}
public static void main(String[] args) {
AutoScale frame = new AutoScale();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
In this example, I create the Panel and paintComponent(). Inside that method, I invoke drawImage() with 6 parameters:
The Image
x Coordinate
y Coordinate
The width of the Frame divided by 2(you can play with the size of your image by adding, substracting or dividing the result of
getWidth())
The height of the Frame divided by 2(same as the width)
The imageObserver, which generally is set to null.
The paintComponent() method gets invoke automatically whenever the size of the Panel changes, so there's no need to use a WindowListener as I suggested earlier.
Note: I use a try-catch block because if it can't find the file, it will throw an Exception.
Hope this was helpful!
I have the following fragment of code, where a JLabel is not displayed unless I move the JFrame out of the screen and back in again. I tried to change the layout from null to BorderLayout or FloatLayout without much luck so far. Any ideas?
public class StartPage extends Main{
// Global variables
private JPasswordField passField = new JPasswordField();
private String infoLabel = "<html>Bla, bla some text</html>";
// CONSTRUCTOR
public StartPage() {
frame.setSize(1400, 1000);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setResizable(false);
startPage.setBounds(0, 0, 1400, 1000);
startPage.setLayout(null);
frame.getContentPane().add(startPage);
// TITLE LABEL
JLabel lblTitle = new JLabel("My Title");
lblTitle.setForeground(Color.RED);
lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
lblTitle.setFont(new Font("Arial Black", Font.BOLD, 30));
lblTitle.setBounds(190, 150, 1000, 85);
startPage.add(lblTitle);
// TEXT LABEL
JLabel areaText = new JLabel(infoLabel, SwingConstants.CENTER);
areaText.setVerticalAlignment(SwingConstants.CENTER);
areaText.setBounds(315, 220, 750, 300);
areaText.setFont(new Font("Arial Black", Font.PLAIN, 15));
areaText.setVisible(true);
startPage.add(areaText);
This line:
frame.setVisible(true);
Should be the last one in your program, it should be called after you've added all your components to it.
Another thing that is wrong with your code is this:
startPage.setLayout(null);
Calling setLayout null will break your GUI, it might seem easy for complex GUIs but here's a good example of what happens when you run it in another machine with different resolution, OS, PLAF, etc. Use one or a combination of layout managers.
You have two solutions, call frame.invalidate() after finishing layout or call setVisible(true) after finishing layout;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm creating a fixture program. I have a page with the button CREATE on. When the user hits create it adds a new button onto the next page. How could I get it so that when the user hits CREATE it adds a new button and the previous buttons move down by say 50 pixels(eg).
createFixtures.setLayout(null); //Create a new fixture panel components
createPanelLabel.setBounds(160, 30, 500, 50);
createPanelLabel.setFont(new Font("TimesRoman", Font.PLAIN, 50));
createPanelLabel.setForeground(Color.WHITE);
southBar4.setBounds(0, 730, 500, 1);
northBar4.setBounds(0, 100, 500, 1);
backButton2.setBounds(20, 750, 150, 60);
createButton2.setBounds(320, 750, 150, 60);
sportLabel.setBounds(30, 150, 500, 40);
sportLabel.setFont(new Font("TimesRoman", Font.PLAIN, 35));
sportLabel.setForeground(Color.WHITE);
descriptionLabel.setBounds(30, 300, 500, 40);
descriptionLabel.setFont(new Font("TimesRoman", Font.PLAIN, 35));
descriptionLabel.setForeground(Color.WHITE);
dateLabel.setBounds(30, 450, 500, 40);
dateLabel.setFont(new Font("TimesRoman", Font.PLAIN, 35));
dateLabel.setForeground(Color.WHITE);
resultLabel.setBounds(30, 600, 500, 40);
resultLabel.setFont(new Font("TimesRoman", Font.PLAIN, 35));
resultLabel.setForeground(Color.WHITE);
sportDropDown.setBounds(250, 150, 200, 40);
descriptionField.setBounds(250, 300, 200, 100);
descriptionField.setFont(new Font("TimesRoman", Font.PLAIN, 20));
descriptionField.setLineWrap(true);
descriptionField.setWrapStyleWord(true);
createFixtures.add(southBar4);
createFixtures.add(northBar4);
createFixtures.add(createPanelLabel);
createFixtures.add(backButton2);
createFixtures.add(createButton2);
createFixtures.add(sportLabel);
createFixtures.add(descriptionLabel);
createFixtures.add(dateLabel);
createFixtures.add(resultLabel);
createFixtures.add(sportDropDown);
createFixtures.add(descriptionField);
container.add(fixtures, "2"); //Labels each panel with a number allowing me to call the number when switching panels also adds panels to main container
container.add(loginPanel, "3");
container.add(createFixtures, "4");
container.add(editFixtures, "5");
container.add(adminFixturesFootball, "6");
container.add(adminFixturesSwimming, "7");
container.add(adminFixturesTennis, "8");
createButton2.addActionListener(new ActionListener() { //Back button listener, switches back to ADMIN fixtures panel
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.show(container, "6");
String descriptionText = descriptionField.getText();
fixtureDescButton.setText( descriptionText );
fixtureDescButton2.setText( descriptionText );
}
});
Again, you should create a factory method that creates your JPanel.
i.e.,
public JPanel createPanel(String buttonText, String dataOnPanel) {
JPanel panel = new JPanel();
JButton myButton = new JButton(buttonText);
myButton.addActionListener(new ButtonListener());
panel.add(myButton);
// add jtextarea if need be with the dataOnPanel String,...
return panel;
}
Edit
You ask
What difference does this make?
You can't add a single component to the multiple containers, but you can create similar components and add them to multiple containers. Using a factory method allows you to do this. For more details on your problem, consider creating and posting a minimal, compilable, runnable example program.
As an aside you appear to be using a null layout and calling setBounds(...) on your components. While this may seem to a newbie the better way to create complex GUI's, it's a fallacy, and more you create Swing GUI's the more you learn to respect and use the layout managers and see that these creatures help immensely in creating flexible, beautiful and if need be, complex GUI's.
Edit 2
Note: if the component has enough significant unique behavior, then I agree with nachokk, create a class to encapsulate it, and then create instances of this class rather than a simple factory method.
Edit 3
The key is that while you can't add a component more than once to a container, you can add new components that use the same model more than once, and that's almost the same thing. Your component's components can even share the same model, for instance your JButtons can share the same Action, your JTextField the same Document if desired.
Edit 4
You state:
A way to increment a button down every time the user hits CREATE. So it adds another button each time, but they move down each instead off spawning on the same position.
Here the layout manager is key. The container holding your JPanels with your buttons will need to use a Layout manager that will accept a new JPanel and place it in the right location. Consider:
The container that accepts the new JPanel can use a GridLayout(0, 1) -- meaning a grid with one column and variable number of rows.
Place this GridLayout using JPanel into the BorderLayout.NORTH position of a BorderLayout using JPanel. This will compress your grid panel to its smallest reasonable size so the JPanels don't expand.
Place the BorderLayout using JPanel into a JScrollPane.
When you add a new JPanel, add it to the GridLayout using JPanel, and then call revalidate() and repaint() on the GridLayout using JPanel so that the new JPanel will be positioned well.
Again, for more details on your problem, consider creating and posting a minimal, compilable, runnable example program.
Edit 5
For example, my MCVE:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class GridButtons extends JPanel {
private JPanel gridPanel = new JPanel(new GridLayout(0, 1));
public GridButtons() {
JPanel topPanel = new JPanel();
topPanel.add(new JButton(new AddRowAction("Add Row")));
JPanel middlePanel = new JPanel(new BorderLayout());
middlePanel.add(gridPanel, BorderLayout.NORTH);
JScrollPane scrollpane = new JScrollPane(middlePanel);
scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollpane.setPreferredSize(new Dimension(400, 400));
setLayout(new BorderLayout());
add(topPanel, BorderLayout.NORTH);
add(scrollpane, BorderLayout.CENTER);
}
private class AddRowAction extends AbstractAction {
public AddRowAction(String name) {
super(name);
}
#Override
public void actionPerformed(ActionEvent e) {
// my factory method here
JPanel panel = new JPanel();
panel.add(new JButton("Button"));
panel.add(new JTextField(20));
gridPanel.add(panel);
gridPanel.revalidate();
gridPanel.repaint();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("GridButtons");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new GridButtons());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
How can I place an object in a specific location (x,y) on a JFrame?
Here find the Absolute Positioning Tutorials. Please do read carefully, as to why this approach is discouraged over using LayoutManagers
To add say a JButton to your JPanel, you can use this :
JButton button = new JButton("Click Me");
button.setBounds(5, 5, 50, 30);
panel.add(button);
Here try this example program :
import java.awt.*;
import javax.swing.*;
public class AbsoluteLayoutExample
{
private void displayGUI()
{
JFrame frame = new JFrame("Absolute Layout Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setOpaque(true);
contentPane.setBackground(Color.WHITE);
contentPane.setLayout(null);
JLabel label = new JLabel(
"This JPanel uses Absolute Positioning"
, JLabel.CENTER);
label.setSize(300, 30);
label.setLocation(5, 5);
JButton button = new JButton("USELESS");
button.setSize(100, 30);
button.setLocation(95, 45);
contentPane.add(label);
contentPane.add(button);
frame.setContentPane(contentPane);
frame.setSize(310, 125);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new AbsoluteLayoutExample().displayGUI();
}
});
}
}
Try these 2... in combination with each other...
setLocation() and setBounds()
Its even better to use GroupLayout, developed by NetBeans team in 2005. WindowsBuilder Pro is a good tool for Building Gui in java
Check out this absolute layout code sample:
Absolute Layout demo
In the class inheriting the frame:
setLayout(null);
In your component:
setLocation(x,y);
Please take a look at my code it is working fine the way I want but the only issue is that I want to add another button opposite my current button and I am not able to do so can any body please help me.
import java.awt.event.*;
import javax.swing.*;
public class Example2 extends JFrame {
public Example2() {
initUI();
}
public final void initUI() {
JPanel panel = new JPanel();
getContentPane().add(panel);
panel.setLayout(null);
panel.setToolTipText("A Panel container");
JButton button = new JButton("Even");
button.setBounds(100, 60, 100, 30);
button.setToolTipText("A button component");
JButton button2 = new JButton("Odd");
button2.setBounds(100, 60, 100, 30);
button2.setToolTipText("A button component");
//Add action listener to button
button.addActionListener(new ActionListener () {
public void actionPerformed(ActionEvent e)
{
//Execute when button is pressed
System .out.println("You clicked the button");
int sum=0;
for(int i=1;i<=100;i++){
if(i%2==0){
System.out.println(i);
sum+=i;
}
}
System.out.println("Sum of even numbers: "+sum);
}
});
panel.add(button);
panel.add(button2);
setTitle("Tooltip");
setSize(500, 400);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Example2 ex = new Example2();
ex.setVisible(true);
}
}
panel.setLayout(null);
That is where it starts to go wrong.
Use layouts. See Laying Out Components Within a Container & Effective Layout Management: Short Course for more details.
Use:
The appropriate layouts.
Possibly nested inside one another.
With appropriate layout padding and component border/insets for white space.
As an aside.
...
button.setBounds(100, 60, 100, 30);
button.setToolTipText("A button component");
JButton button2 = new JButton("Odd");
button2.setBounds(100, 60, 100, 30);
...
Did you notice how the bounds of the two buttons were identical? What do you think happens when you put two components of the same size in the same place?
You have to change panel.setLayout(null) to layout you need. For example:
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
or
panel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER));
Andrew Thompson +1 ,
Here are some usefull links :
A Visual Guide to Layout Managers
Using Layout Managers
Adding space between components