I have created an Object that extends JPanel and draws beginning at (0,0) a short animation). It works great on its own but I would like to add a button above it to handle small actions for the animation.
So in my main class I did the following:
JFrame f = new JFrame("Test");
JButton testButton = new Button("BUTTON");
MyAnimationDrawer drawing1 = new MyAnimationDrawer();
What i want to do:
How would I add the button and my Object to the JFrame so that the top left corner acts as (0,0)? Exactly as shown in my image link.
By using BorderLayout.
Add drawing panel on CENTER of JFrame. Something like:
frame.add(drawingPanel, BorderLayout.CENTER);
Add button on upper panel and then add upper panel on NORTH of JFrame:
upperPanel.add(button);
frame.add(upperPanel, BorderLayout.NORTH);
As brano88 has stated, the simplest way to achieve this is by using BorderLayout. Below is a short example of what you desire using this layout. As BorderLayout is the default layout manager for a JFrame, you do not need to explicitly set it, just use its fields out of the box.
public class MyPanel extends JPanel {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.RED);
g2d.fillRect(0, 0, getWidth(), getHeight());
}
public static void main(String[] args){
JFrame frame = new JFrame("My frame");
frame.setSize(800,600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
//Button Panel
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton("Click me!"));
//Drawing panel
MyPanel panel = new MyPanel();
frame.add(panel, BorderLayout.CENTER);
frame.add(buttonPanel, BorderLayout.NORTH);
frame.setVisible(true);
}
}
Related
When I run the below code, I am unable to see the background color as red. It's showing default one. Is there anything that I have to add to these lines?
import java.awt.*;
import java.awt.Graphics;
import javax.swing.*;
public class gfix extends JPanel {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(80, 100, 150, 75);
}
public static void main(String[] args){
gfix gg=new gfix();
JFrame frame = new JFrame("RISK");
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(null);
frame.add(panel);
JButton button = new JButton("test");
button.setBounds(100, 100, 150, 150);
panel.add(button);
frame.setVisible(true);
}
}
Your are overriding painGraphics() in gfix class so add gfix class object into your frame not Java provided JPanel class object.
gfix gg=new gfix();
JFrame frame = new JFrame("RISK");
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//JPanel panel = new JPanel(); Not needed
//panel.setLayout(null);
frame.add(gg);
JButton button = new JButton("test");
button.setBounds(100, 100, 150, 150);
gg.add(button);
frame.setVisible(true);
for g.fillRect(80, 100, 150, 75); give proper panel bounds to fill complete panel background. OR use int width = getWidth();
int height = getHeight(); in paintGraphics to get actual height and width.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class gfix {
public static void main(String[] args) {
JFrame frame = new JFrame("RISK");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setBackground(Color.RED);
frame.add(panel);
JButton button = new JButton("test");
// adjust numbers as needed
button.setMargin(new Insets(20,40,20,40));
panel.add(button);
// adjust numbers as needed
panel.setBorder(new EmptyBorder(10,40,50,200));
frame.pack();
frame.setVisible(true);
}
}
Other tips:
Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or combinations of them along with layout padding and borders for white space.
Provide ASCII art or a simple drawing of the intended layout of the GUI at minimum size, and if resizable, with more width and height - to show how the extra space should be used.
Please learn common Java nomenclature (naming conventions - e.g. EachWordUpperCaseClass, firstWordLowerCaseMethod(), firstWordLowerCaseAttribute unless it is an UPPER_CASE_CONSTANT) and use it consistently.
I'm trying to create an interface with Swing.
This is my code:
public class JavaApplication30
{
public static void main(String[] args) throws IOException
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.X_AXIS));
frame.setPreferredSize(new Dimension(1280, 720));
frame.setResizable(false);
frame.setContentPane(new JPanel()
{
BufferedImage image = ImageIO.read(new File("C:\\Users\\user\\Documents\\NetBeansProjects\\JavaApplication29\\src\\eila.jpg"));
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 0, 0, 1280, 720, this);
}
});
JPanel a = new JPanel();
a.setAlignmentX(Component.LEFT_ALIGNMENT);
a.setPreferredSize(new Dimension(150, 500));
a.setMaximumSize(new Dimension(150, 500));
a.setOpaque(false);
a.add(Box.createRigidArea(new Dimension(5,50)));
JButton amico = new JButton("Amico");
a.add(amico);
a.add(Box.createRigidArea(new Dimension(5,20)));
amico.setPreferredSize(new Dimension(150, 50));
JButton bello = new JButton("Bello");
a.add(bello);
a.add(Box.createRigidArea(new Dimension(5,20)));
bello.setPreferredSize(new Dimension(150, 50));
JButton compagno = new JButton("Compagno");
a.add(compagno);
compagno.setPreferredSize(new Dimension(150, 50));
frame.getContentPane().add(a);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class ImagePanel extends JComponent {
private Image image;
public ImagePanel(Image image) {
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
}
I set the button alignment to the left, but my buttons are still centered.
This didn't happen without paintComponent for the background.
Why is this? How can I align the buttons on the left?
I set Alignment to left, but my buttons are centered
The setAlignmentX(...) is only a hint for how the "panel" should be aligned in its parent panel. When you add the buttons to the panel, what matters is the layout manager of the panel.
By default a JPanel uses a FlowLayout. Also by default when you create a FlowLayout, the components added to the panel are centered aligned in the space of the panel.
Change the layout manager to be a FlowLayout with the components left aligned. Read the FlowLayout API for the proper constructor to use.
Also, you can provide a default gap between the buttons, so there is no need for the Box.createRigidArea(...). The component is really meant to be used when you use a BoxLayout.
So I set the setSize(500,500).. add some panels, the sum of panels Y is 500 like the JFrame but executing it shows an count Y of 525 am I missing something?
JPanel panel = new JPanel();
panel.setLayout(null);
getContentPane().add(panel);
//--------------------
JPanel top_panel = new JPanel();
top_panel.setLayout(null);
top_panel.setBackground(Color.blue);
top_panel.setBounds(0, 0, 500, 40);
panel.add(top_panel);
//------------------------------
JPanel middle_panel = new JPanel();
middle_panel.setLayout(null);
middle_panel.setBackground(Color.yellow);
middle_panel.setBounds(0, 40, 500, 385);
panel.add(middle_panel);
//-----------------------------
JPanel bottom_panel = new JPanel();
bottom_panel.setLayout(null);
bottom_panel.setBackground(Color.black);
bottom_panel.setBounds(0, 425, 500, 75);
panel.add(bottom_panel);
setSize(500,500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
setLocationRelativeTo(null);
40+385+75 = 500 but to show all the panels i must
setSize(500,525);
then it fits
here's an image:
The frame size is the light blue rectangle outside bounds including the title bar. Your panels are appearing in the inner bounds which is frame size less than the frame border and frame title bar. Do you see how your marked space at the bottom is strangely the same height as the title bar?
After adding your panels/component to the frame and just before calling frame.setVisible(true), call frame.pack().
It would be also preferable if you embrace a layout manager (such as FlowLayout) and when necessary call setPreferredSize and let the layout manager do the layout. Normally one would call setPreferredSize over setBound, setSize, setMininumSize, setMaximumSize.
import javax.swing.*;
import java.awt.*;
public class FrameSize {
private JFrame frame;
FrameSize create() {
frame = createFrame();
frame.getContentPane().add(createContent());
return this;
}
private JFrame createFrame() {
JFrame frame = new JFrame(getClass().getName());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
return frame;
}
void show() {
// frame.setSize(500, 500);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
private Component createContent() {
JPanel panel = new JPanel(null);
JPanel topPanel = new JPanel(null);
topPanel.setBackground(Color.blue);
topPanel.setBounds(0, 0, 500, 40);
panel.add(topPanel);
JPanel middlePanel = new JPanel(null);
middlePanel.setBackground(Color.yellow);
middlePanel.setBounds(0, 40, 500, 385);
panel.add(middlePanel);
JPanel bottomPanel = new JPanel(null);
bottomPanel.setBackground(Color.black);
bottomPanel.setBounds(0, 425, 500, 75);
panel.add(bottomPanel);
panel.setPreferredSize(new Dimension(500, topPanel.getBounds().height + middlePanel.getBounds().height + bottomPanel.getBounds().height));
return panel;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new FrameSize().create().show();
}
});
}
}
You shouldn't be setting size or calling setSize(...) or setBounds(...) as that's setting you up for similar problems in the future, or worse problems when you try to show your GUI on a different platform. Instead let the preferredSizes of your components and the layout managers do this work for you. If you absolutely must set the size of a component, then override getPreferredSize() and return a Dimension that is calculated to work for you. And yes, as per javajon, you should call pack() on the JFrame before displaying it.
For more discussions on the null layout, please read what one of the best Swing experts on this site, MadProgrammer, has to say in his answer here.
i've gone about setting the background Image of my JFrame but now my components are (I assume) stuck behind it. I've tried reading about top level containers but I just can't get my head around it T_T. Any one have any ideas ? Maybe I need to find another way to set the background image ? Thank you for any help. :
#SuppressWarnings("serial")
public class CopyOfMainMenu extends JFrame {
//Running the GUI
public static void main(String[] args) throws IOException {
CopyOfMainMenu gui2 = new CopyOfMainMenu();
gui2.mainPanel();
}
public void thepanel () throws IOException {
// GridBagLayout/Constraint
GridBagConstraints gridbagc = new GridBagConstraints();
gbc.insets = new Insets(15, 15, 15, 15);
JFrame frame = new JFrame();
JPanel panel = new JPanel(new GridBagLayout());
// Creating JButtons/Icons
panel.add(buttonTwo, gbc); //SCOREBOARD
panel.add(buttonThree, gbc); //INSTRUCTIONS
// JButton size's
button.setPreferredSize(new Dimension(400, 35))
buttonTwo.setContentAreaFilled(false);
buttonThree.setBorder(BorderFactory.createEmptyBorder());
buttonThree.setContentAreaFilled(false);
}
}
Again, thanks in advance for any help.
You never add the panel anywhere (if you did, it would paint over the image). However, it's possible to use a JLabel as the container:
JComponent panel = new JLabel(new ImageIcon(ImageIO.read(new File("res/FinalBG.png"))));
panel.setLayout(new GridBagLayout());
...
// continue adding the components as before
...
frame.add(panel);
(or set the label as the content pane, which works just as well).
Inside the JFrame, override the paint method and draw your image using the Graphics object:
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(image, width, height, null);
}
void setUpGUI() {
JFrame frame = new JFrame();
frame.setContentPane(new Board());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setVisible(true);
}
class Board extends JPanel {
#Override
public void paintComponent(Graphics g) {
setLayout(new GridLayout(10, 9));
JButton b = new JButton("hello");
add(b);
g.setColor(Color.orange);
g.fillRect(20, 50, 100, 100);
}
}
For some reason the code only shows the rectangle, not the JButton. What am I doing wrong? Thanks!
The paintComponent() method is for painting only. You never create and add components to a panel in a painting method. Get rid of that code.
Also add a super.paintComponent() at the start of the method.
To add components to a panel you do something like:
Board board = new Board();
board.setLayout(...)
board.add(...);
or in the constructor of the board class you can set the layout and add components.