Java Swing JPanel Sizes - java

I would like to be able to have a JPanel within my JFrame of a fixed size 400x400.
I would also like the to be a 20px wide border all around it.
The main problem is the following code doesnt stick it its size.` JScrollPane runningAni = new JScrollPane(new views.cRunningAnimation(
model));
runningAni.setMaximumSize(new Dimension(400,400));
this.setSize(new Dimension(600,600));
this.add(runningAni,BorderLayout.CENTER);`
When doing this the runningAni panel just strethces accross the whole frame.
public void paint(Graphics g) {
this.setBackground(new Color(0,255,0));
}
I know this because my full frame paints itself green rather than just the JPanel (The above paint code is for my panel not the frame)
How would i create the panel so it always stays the same size and so there is always a 20px colored border around it?

BorderLayout ignores the size. You need to set a LayoutManager that either allows you to set the size to a fixed size or one that cares for the sizes set. There are different layout managers that allow this (e.g. GrindBagLayout or no layout manager at all). Some are not that easy to use (e.g. GridBagLayout). What to use depends on the rest of the layout.
You could probably use a layout panel that contains your custom panel. The layout panel needs an appropriate layout manager and could be put into the center of the BorderLayout. This would mean nearly no modifications to existing layout code.
The whole point of BorderLayout is to fill the center with the center component.

Don't override the paint() method to set the color of the panel. Use:
panel.setBackground(...);
When you create the panel.
How would i be able to set a border around my Jpanel
See How to Use Borders.

Just set your layout to null, to what ever class your adding your JPanel.
Then use the setBounds() method to set your location and size!
For example:
public class Main extends JFrame{
YourPanelClass panel = new YourPanelClass();
public Main(){
// I didn't want to put all the, everyday JFrame methods...
setLayout(null);
/*
First two coordinates indicate the location of JPanel inside JFrame.
The seconds set of coordinates set the size of your JPanel.
(The first two coordinates, 0 and 0, tell the JPanel to start at the
top left of your JFrame.)
*/
panel.setBounds(0, 0, 100, 100);
add(panel);
}
}
And i would GREATLY recommend using the paintComponent() method.
For instance:
(Obviously you put this in your JPanel's class.)
public void paintComponent(Graphics g){
super.paintComponent(g); // don't forget this if you are going to use this method.
//Basically this makes your JPanel's background green(I did it this way because I like doing it this way better.)
g.setColor(new Color(0, 255, 0));
g.fillRect(0, 0, getWidth(), getHeight());
}
Please don't forget to thumbs up if this helped!

setPreferredSize()
setMinimumSize()
setMaximumSize()
should do the trick

Related

Can I add a rectangle to a Jpanel in java swing and specify constraints for it using GridBagConstraints?

I'm pretty new to GUI and Java as a whole so I hope that I can explain this well enough and understand people's answers.
For a school project, I need to put a bunch of stuff on some rectangles but I'm having issues even adding one rectangle properly.
From researching online, this is what I have (the JPanel and GridBagConstraints are just there to show what I'd like to use):
public class GUI extends JPanel
{
public static void main (String [] args)
{
GUI g = new GUI();
JFrame window = new JFrame("Java Window");
window.setSize(1280, 960);
window.add(g);
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel layout = new JPanel(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
}
#Override
public void paintComponent(Graphics g)
{
Color boxColour = new Color(194, 190, 190);
super.paintComponent(g);
g.setColor(boxColour);
g.fillRect(10, 10, 100, 100);
}
}
So right now, the rectangle appears in the window. But how can I add constraints to it? Is that possible? I would think that I should use JPanel to keep everything more organized since there will be many components so I tried adding this:
layout.add(g);
window.add(layout);
window.setVisible(true);
However, the rectangle no longer appeared. What am I doing wrong and how can I fix it and add constraints to my shapes? Thanks!
In your first scenario, the default layout manager of the frame is the BorderLayout and you are adding your "g" panel to the BorderLayout.CENTER. So based on the rules of the BorderLayout your "g" panel will take up all the space available in the frame. So you have plenty of space to paint your rectangle.
However, in your second scenario, your "layout" panel is using the default layout manager of a JPanel which is a FlowLayout which respects the preferred size of any component added to it.
The preferred size of the "g" panel is 10 x 10. So, when you add the "g" panel to the "layout" panel there is nothing to see because all you custom painting is done outside the bounds of the panel.
You need to override the getPreferredSize() method of your GUI panel to return a preferred size of (120, 120) so you can see your rectangle painted with a 10 pixel border around all the edges.
Read the section from the Swing tutorial on Custom Painting for more information and working examples demonstrating how to override the `getPreferredSize() method.
You will also need to read the Swing tutorial on How to Use GridBagLayout for example of using the constraints to add multiple components.

Image only paints within original bounds

I want to animate several jpgs in a JFrame, I'll show you some extracts:
My class constructor that extends JFrame
super(title);
setLayout(null);
setResizable(false);
setSize(Settings.windowWidth, Settings.windowHeight);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
My class constructor that extends JPanel
i = new ImageIcon(image).getImage();
setSize(i.getWidth(this),i.getHeight(this));
setBounds(x, y, i.getWidth(this), i.getHeight(this));
The overwritten method
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(i, getX(), getY(), null);
}
Yes, I know null layout isn't preferrable, but unless you have a better idea for absolute positioning I'll stick with it for now.
Above code does paint the image, starting at (x,y), but not completely.
For 50 and 100 it shows this:
Which is pretty much: It only paints the image within a 256x256 box (image dimensions) from 0,0, no matter where it has been relocated to.
Any advice, help, solutions, suggestions?
If you need more code, ask me, just don't feel like putting everything around it in here, too ;)
There is no need for custom painting:
Add the ImageIcon to a JLabel and add the JLabel to a JPanel
Change the location of the label on the panel when you want to animate it.
Or, if you do custom painting then there is no need for a null layout.
You override the getPreferredSize() method of the JPanel and add your panel to the frame.
Then in the paintComponent() method you can paint the image where every you want withing the bounds of the preferred size that you set.
My gut feeling is you don't understand how component painting actually works...
First, you do this...
i = new ImageIcon(image).getImage();
setSize(i.getWidth(this),i.getHeight(this));
setBounds(x, y, i.getWidth(this), i.getHeight(this));
Then you do this...
g.drawImage(i, getX(), getY(), null);
which seems to be painting the image at a offset position from the components origin, but since the component is sized to match the size of the image, the image is cropped at the component boundaries.
When a component is painted, the Graphics context's origin is set to the components location, meaning that 0x0 is now the components top/left corner.
You can test this by using setBorder(new LineBorder(Color.RED)), which will show you the physical bounds of the component
In your case, something like
g.drawImage(i, 0, 0, this);
In your case, you should be moving the component not the image.
Personally, I'd add the JPanel to the JFrame using a BorderLayout, then you can simply move the image anywhere within the context of the component itself. Remember to override getPreferredSize to return an appropriate size for your purposes so the frame can be packed around it more effectively.
It's tricky to do animation with components (not impossible, there's just a lot to take into account), generally it's just easier to paint directly to a canvas like a JPanel, but that's me
See Painting in AWT and Swing and Performing Custom Painting for more details about how painting works

JLabel and JTextArea not working

I am making a window that has a large text area and a small text area under it. This is what i have so far:
This is the code I have for it:
JPanel window=new JPanel(){
protected void paintComponent(Graphics g){
super.paintComponent(g);
ImageIcon ii=new ImageIcon("textEffect.png");
Image i=ii.getImage();
g.drawImage(i,0,0,null,this);
}
};
JLabel label=new JLabel("Say: ");
JTextArea dialog=new JTextArea(20,50);
JTextArea input=new JTextArea(1,46);
JScrollPane scroll=new JScrollPane(
dialog,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
);
//main method
public static void main(String[] args){
new Window();
}
//Makes window and starts bot
public Window(){
super("Pollockoraptor");
setSize(600,400);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
dialog.setEditable(false);
dialog.setOpaque(false);
dialog.setBackground(new Color(0, 0, 0, 0));
dialog.setLineWrap(true);
input.addKeyListener(this);
label.setVerticalTextPosition(SwingConstants.BOTTOM);
label.setHorizontalTextPosition(SwingConstants.LEFT);
window.add(scroll);
window.add(label);
window.add(input);
window.setBackground(new Color(97,118,131));
add(window);
setVisible(true);
}'
How do I make the larger textarea partially transparent so I can see the background and how do I move "Say:" to be infront of the smaller textarea?
JPanel uses a FlowLayout by default. You'll want to change the layout manager, personally, I'd recommend something like GridBagLayout, but that's just me.
See Laying Out Components Within a Container for more details
To make the JTextArea see through, you're going to have to make the JScrollPane and it's JViewPort transparent as well.
Swing only knows how to paint fully opaque or fully transparent components. You can create a translucent effect by making the component transparent and overriding it's paintComponent method and using an AlphaComposite or painting a with a Color which has an alpha value set to something below 255
For example...
Can not draw image on JTextArea background when using Nimbus Look And Feel
JTextArea not selectable, but still showing a "ghost" cursor
Swing Graphics on JFrame
And general advice...
Key Bindings over KeyListener
Override getPreferredSize of your custom component to get better results when been laid out
Use JFrame#pack over setSize, this will calculate the window size based on the needs of the content and take into account the window frame decorations as well
How do I make the larger textarea partially transparent so I can see the background
Check out Backgrounds With Transparency for problems when using a transparent background and a general purpose solution you can use to you don't need to do custom painting all the time.

Get Resource Image and Use As JFrame Background [duplicate]

This question has been asked a lot but everywhere the answers fall short. I can get a JFrame to display a background image just fine by extending JPanel and overriding paintComponent, like so:
class BackgroundPanel extends JPanel {
private ImageIcon imageIcon;
public BackgroundPanel() {
this.imageIcon = Icons.getIcon("foo");
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(imageIcon.getImage(), 0,0,imageIcon.getIconWidth(),imageIcon.getIconHeight(),this);
}
}
But now, how do you add a component on top of that background?
When I go
JFrame w = new JFrame() ;
Container cp = w.getContentPane();
cp.setLayout(null);
BackgroundPanel bg = new BackgroundPanel();
cp.add(bg);
JPanel b = new JPanel();
b.setSize(new Dimension(30, 40));
b.setBackground(Color.red);
cp.add(b);
w.pack()
w.setVisible(true)
It shows the little red square (or any other component) and not the background, but when I remove cp.setLayout(null);, the background shows up but not my other component. I'm guessing this has something to do with the paintComponent not being called by the null LayoutManager, but I'm not at all familiar with how LayoutManagers work (this is a project for college and the assignment specifically says not to use a LayoutManager).
When i make the image the background has to display null (and so, transparant (??)) the red square shows up so it might be that the background is actually above my other components.
Does anyone anyone have any ideas?
Thanks
When using null layout (and you almost never should) you have to supply a bounds for every component, otherwise it defaults to (0 x,0 y,0 width,0 height) and the component won't display.
BackgroundPanel bg = new BackgroundPanel();
cp.add(bg);
isn't supplying a bounds. You'll need to do something like:
BackgroundPanel bg = new BackgroundPanel();
bg.setBounds(100, 100, 100, 100);
cp.add(bg);
Which would make bg size 100 x 100 and place it at 100 x, 100 y on the frame.
Look in the documentation on the Root Pane for all the information you need. Note the availability of the layered pane and the glass pane as well as the content pane.
By default all components have a 0 size. Just because you do some painting on a component doesn't give the component a size. You are still responsible for setting the size. That is why you should always use a layout manager. It looks after all this size stuff for you so you don't have to worry.
I don't know why newbies always think they can't use a layout manager. Yes it takes a couple of more minutes to learn, but it saves you a lot of grief in the long run.
Background Panel shows a couple of approaches. Again they both assume you use a layout manager, so you may need to set the size manually.

Painting over the top of components in Swing?

I have a JPanel added to a JViewport, and the panel has several other panels added to it. I'm trying to implement a dragging selection, where you can select more than one component by dragging the mouse. The only problem I'm facing is that the selection rectangle is being painted behind the components added to the main JPanel. How can I paint over the top of them?
My structure is as follows: JFrame -> ContentPane -> JLayeredPane -> JScrollPane -> JPanel -> JPanel [].
Design draft for college assignment:
As you can see, the rectangle is behind the other panels.
This is what I'm already doing (on a much simpler level obviously), and Swing paints the rectangle underneath the components added to it.
This is one case where you should override the paint() method of the panel and not the paintComponent() method. Then the custom painting will be done AFTER all the child components have been painted.
Use a Layered Pane:
http://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html
This allows you to create overlapping components.
Use a glass pane to handle the drag painting, and possibly events as well:
http://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html#glasspane
hot really sure what do you really needed and final effect, maybe is there two another ways painting to
1) GlassPane
2) Viewport
you can put that together, carrefully Insets to the visible Rectanle
Without seeing your actual code, it is difficult to say what you are doing wrong. However, I can still say what I would do:
Create a JPanel that represents the whole area where you want to draw, which — of course — contains every component.
Override that panel its paintComponents(Graphics) like this (EDITED, notice the s is now the last character from the method name):
#Override
public void paintComponents(Graphics g)
{ // ^
super.paintComponents(g);
// Draw your selection rectangle:
g.setColor(Color.RED);
g.drawRectangle(selectionRectangle);
}
Okay, this is what I've decided to do in the end:
I'm not sure if this is the best way to do it, but it seems to work okay.
Note: Using MigLayout.
In the constructor of the JPanel lying underneath the colored blocks.
...
this.add(new JPanel() {
#Override
public boolean isOpaque() {
return false;
}
#Override
public void paintComponent(Graphics g) {
if (dragShape != null) {
g.setColor(Colors.SECONDARY);
g.setStroke(new BasicStroke(2));
g.draw(dragShape);
}
}
}, "pos 0 0, width 100%, height 100%", 0);
...
Custom painting on top of Swing components is facilitated by JLayeredPane. This article describes an abstract base class that facilitates overpainting specific areas (like selection rectangles or component bounds).

Categories

Resources