Problems with setting JPanel's colour - java

Here's my canvas class extending JPanel:
package start;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Board extends JPanel
{
private static final long serialVersionUID = 1L;
public Board() {}
public void paintComponent(Graphics g)
{
int width = getWidth();
int height = getHeight();
this.setBackground(Color.green);
g.setColor(Color.black);
g.drawOval(0, 0, width, height);
}
}
Here's the method where I'm calling it:
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Hello");
frame.setPreferredSize(new Dimension(700, 700));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Board b = new Board();
frame.getContentPane().add(b);
frame.pack();
frame.setVisible(true);
}
But this shows the oval on the default colour. I also tried without the this., and then tried setting the colour of b, and setting the colour inside the constructor, but none of these worked. What's wrong?
EDIT: Sorry for not making thing clear, my goal was to display a thin black oval on a green background.

In the paintComponent method you do not have to use setBackground to change the colour of the JPanel. That should be done outside of paintComponent. paintComponent will probably use the colour of the background before you change it.
There are a number of things you can try. One, is to set the colour in the constructor and then call the super class' paintComponent first like this:
public Board() {
this.setBackground(Color.GREEN);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
g.setColor(Color.BLACK);
g.drawOval(0, 0, width, height);
}
Also note the color constants are all upper case. i.e. BLACK or GREEN.
If you want to change the background colour dynamically then you can do so in the event handler such as mouseEntered or actionPerformed etc.

While the code does not exactly make clear what's your intent i try to fix some issues:
If you want a green background, do as #vincent told you. YOu should see a black oval in green background. The "super.paintComponent" will fill its area with the components background automatically if the panel is opaque.
If you want a green oval on white background, maybe with black border
public void paintComponent(Graphics g)
{
int width = getWidth();
int height = getHeight();
super.paintComponent(g);
g.setColor(Color.GREEN);
g.fillOval(0, 0, width, height);
g.setColor(Color.BLACK);
g.drawOval(0, 0, width, height);
}
EDIT
i forgot super

Related

Draw border below the text of a component in Swing

I've created a custom border class where I fill a rectangle to act as a background for a component. Note that this border will have a more complex shape in the future, not just a simple rectangle.
When I add my border to a component, the text of the component will appear behind the border and make the text unreadable. (The result is depicted in the image below.)
Is there a way to draw the border below the text?
My border class:
public class CustomBorder extends AbstractBorder {
private static final long serialVersionUID = 1L;
#Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(new Color(125, 125, 125, 255));
g2d.fillRect(x - 10, y - 10, width + 20, height + 20);
}
#Override
public Insets getBorderInsets(Component c) {
return super.getBorderInsets(c);
}
#Override
public Insets getBorderInsets(Component c, Insets insets) {
return super.getBorderInsets(c, insets);
}
#Override
public boolean isBorderOpaque() {
return super.isBorderOpaque();
}
}
Main:
public static void main(String[] args) {
JLabel label = new JLabel("JLabel text");
label.setBorder(new CompoundBorder(new EmptyBorder(50, 20, 20, 20), new CustomBorder()));
JFrame frame = new JFrame("");
frame.setLayout(new FlowLayout());
frame.setSize(200, 200);
frame.add(label);
frame.setVisible(true);
}
Edit: I should also note that I will be using this border to a chat program, which will be using bubble-shaped messages, so a colored square using setBackground() is a no-no.
See A Closer Look at the Paint Mechanism which explains how the painting is done. The border is painted after the text of the label is painted.
What exactly are you trying to do? Your border painting code doesn't make sense. You are trying to fill a rectangle equal to the width/height of the component + 20 pixels, which means you are trying to paint an area larger than the component.
If you are just trying to paint a background on a label then you can use:
label.setOpaque( true );
label.setBackground(...);
Edit: The code in this answer that was linked in the comment section below solved the problem.
You could always use g2d.drawString().
However, if that is not to be utilised for some reason, you could just do:
JLabel l = new JLabel("foo");
l.setBackground(Color.GRAY);
l.setOpaque(true);

Rectangle2D, borders go missing?

Helo guys,
my problem is that sometimes if my Rectangle2D gets a big width or height its bottom,left border splits and no longer makes a continous border and if I even make it wider the border goes smaller and smaller, like if there were a limitation of how long a rectangles border can be... It is really confusing and so far I have not found the solution :S I put there a link to a picture so you can see for yourself.
new Rectangle2D.Double(mojrectangle.getUpperleftPointmojRectangle().getX(), mojrectangle.getUpperleftPointmojRectangle().getY(),1000,1000)
repaint();
thanks for your help..
BTW I have the same problem with Arc2D if it gets really big
UPDATE: I removed from the function the setStroke command and now it draws it correctly, but in the future I will need to set the Rectangles stroke so it leaves me sad.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2=(Graphics2D)g;
//g2.setStroke(stroke);
g2.draw(rectangle);
}
Here I put an example code of my project, please try it with g2.setStroke(selectedstroke)- it wont work, and without it...I hope I explained myself clear .
package com.awtgraphicsdemo;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.JComboBox;
public class AWTgraphicsdemo extends Frame {
final float dash[] = {10.0f};
final float solid[] = {1000.0f}; // these must be in an Array
float lineWidth[]={2.0f,4.0f,6.0f,8.0f,10.0f}; // width of the drawing line
String[] lineWidthString={"2.0","4.0","6.0","8.0","10.0"};
JComboBox strokecombobox=new JComboBox(lineWidthString);
BasicStroke selectedStroke = new BasicStroke(lineWidth[0],BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER, 10.0f, solid, 0.0f);
public AWTgraphicsdemo(){
super("Java AWT Examples");
prepareGUI();
}
public static void main(String[] args){
AWTgraphicsdemo awtGraphicsDemo = new AWTgraphicsdemo();
awtGraphicsDemo.setVisible(true);
}
private void prepareGUI(){
setSize(400,400);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
}
#Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(selectedStroke);
g2.draw (new Rectangle2D.Double(10, 10, 1000, 900));
Font font = new Font("Serif", Font.PLAIN, 24);
g2.setFont(font);
g.drawString("Welcome to TutorialsPoint", 50, 70);
g2.drawString("Rectangle2D.Rectangle", 100, 120);
}
}
Helo again,
I figured out my problem, it was in the properties of stroke,so after some lenght of the compoment the stroke got activated which made changed to the drawn shape.By modifying the strokes solid array I was able the get the result I wanted.
Thank you for your help and suggestions :)
Take Care
Better to:
Not override paint(...) in top level windows (as MadProgrammer states) since this also changes painting of borders and child components -- a dangerous thing to do.
Instead override paintComponent(...) of a JPanel (again as MadProgrammer states) and place that JPanel into your top level window.
Don't set the Stroke of the Graphics object passed into your painting method, but rather a copy of the Graphics object so not to have side effects down the road.
e.g.,
public class MyPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setStroke(....);
// do drawing with g2 here
g2.dispose();
}
}

Java - Top inset not returning the proper value when painting

having a problem with top insets not giving the proper value when painting ... i am looking for y to be just under the title bar but it is not working correctly and putting it 25 pixels from the top where as the title bar only accounts for about 14 pixels .
Game Frame :
import java.awt.Dimension;
import javax.swing.JFrame;
public class gameFrame extends JFrame {
static int width = 400;
static int height = 400;
static int topinset;
static int FPS = 30;
public gameFrame(){
gamePanel gamePanel = new gamePanel();
gamePanel.setPreferredSize(new Dimension(width,height));
Thread thread = new Thread(gamePanel);
this.add(gamePanel);
this.setResizable(false);
this.setSize(width, height);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
topinset = this.getInsets().top;
thread.start();
}
public static void main(String[] args){
gameFrame gameFrame = new gameFrame();
}
}
Game Panel :
import java.awt.Graphics;
import javax.swing.JPanel;
public class gamePanel extends JPanel implements Runnable {
public gamePanel(){
this.setBounds(0,0,gameFrame.width,gameFrame.height);
this.setVisible(true);
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawString("Width: "+ gameFrame.width + " Height: " + gameFrame.height, 0, gameFrame.topinset);
}
#Override
public void run() {
while(true){
repaint();
try {Thread.sleep(1000*gameFrame.FPS);}
catch (InterruptedException e) {}
}
}
}
You are doing your custom painting on the panel so there is no need to worry about the offsets of the frame. Just use the getWidth() and getHeight() methods to get the current size of the panel.
If you want your panel to be (400, 400), then override the getPreferredSize() method of your panel class to return that dimension. Then use frame.pack() and the frame will size itself properly to include the panel size and the frame decorations.
There is no need for static variables. Those variables should just be instance variables or constants.
There is no need for the setBounds() since the layout manager will determine the size/location of the panel in the frame.
There is no need to make the panel visible since is it visible by default.
Follow Java naming conventions. Class names should start with an upper case character.
Why are you doing custom painting? Why not just add a JLabel to the NORTH of the frame and display your text in the label?
Start by taking a look through Working with Text APIs
Text rendering is typically done from the base line, meaning text will painted above the y position you specify
As has already being stated, a components Graphics context is translated before it's painted so that the 0x0 position will be the top/left corner of the component
In the following example, the first String will not appear on the screen, as it's base line is along the top edge of the component, whereas the second String has being adjusted so that it's ascent line is along the top top
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics g2d = (Graphics2D) g.create();
FontMetrics fm = g2d.getFontMetrics();
g2d.drawString("Hello", 0, 0);
g2d.drawString("Hello", fm.stringWidth("Hello"), fm.getAscent());
g2d.dispose();
}

Java not drawing desired graphics

This is a pretty simple program that just draws a white rectangle in a pop-up window. The program compiles and runs no problem, and the windoe pops up, but there is nothing in it, it's just grey. Why isn't anything drawing?
import java.awt.*;
import javax.swing.*;
public class DrawPanel extends JPanel {
public void paintcompnent(Graphics g) {
int width = getWidth();
int height = getHeight();
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(10, 10, 200, 200);
}
public static void main(String[] args) {
DrawPanel panel = new DrawPanel();
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.add(panel);
window.setSize(550,550);
window.setVisible(true);
}
}
public void paintcompnent(Graphics g)
Should be
public void paintComponent(Graphics g)
You have not correctly overridden the method. It should be:
#Override
protected void paintComponent(Graphics g) {}
Note the use of the #Override annotation, which will prevent you from making this mistake in the future.
After fixing the overridden method name, it still won't paint anything because you are filling the rectangle in white and then painting white lines on top. You need to use setColor() to set something other than white to see the lines.

Java isn't displaying rectangle?

I'm trying it to display a rectangle at the specified location but it isn't showing up. The background is magenta but the rectangle is not there.
Also: How can I access more colors besides the "Color.(insert very few options here)"
import javax.swing.*;
import java.awt.*;
class Screensaver {
private final static int FRAME_HEIGHT = 600;
private final static int FRAME_WIDTH = 600;
public static void main(String[] args){
JFrame win;
Container contentPane;
Graphics g;
win = new JFrame();
win.setSize(FRAME_WIDTH, FRAME_HEIGHT);
win.setVisible(true);
contentPane = win.getContentPane();
contentPane.setBackground(Color.MAGENTA);
g = contentPane.getGraphics();
g.setColor(Color.BLACK);
g.fillRect(80, 350, 400, 250);
}
}
You shouldn't be painting in main(); it would be better to extend JPanel, change paintComponent(), and add the panel to the JFrame.
public class PaintPanel extends JPanel {
public PaintPanel() {
setBackground(Color.MAGENTA);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g); // This paints the background
g.setColor(Color.BLACK);
g.fillRect(80, 350, 400, 250);
}
}
And in main():
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.add(new PaintPanel());
frame.setVisible(true);
}
If you want to make your own Colors, you can use the new Color(int red, int green, int blue) constructor.
If you're going to draw stuff create a class that inherits from a Swing container, JComponent, JPanel, etc. and override the paint(Graphics g) method. If you see the magenta background then contentPane must have been added. What's probably happening is its painting the magenta background over your rectangle, but that's just a guess. Try this...
public class ContentPane extends JComponent {
public ContentPane() {
}
#Override
public void paint(Graphics g) {
g.setColor(Color.MAGENTA);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
g.fillRect(80, 350, 400, 250);
}
}
Then in your main class instantiate an object of the ContentPane class and add it to your JFrame. The call to repaint() is probably unnecessary but that will make sure it gets painted. You can also try messing around with the paintComponent(Graphics g) method, there is a difference between the two, I believe its the order they're called from the update method but I'm probably wrong about that, however that should solve your problem.
As for colors, consult the API. You can pass RGB values into the Color constructor to create all sorts of colors. Color color = new Color(int red, int green, int blue). I think that is the easiest way to create custom colors but like I said its all in the API. Hope this helps.
Try this :
import javax.swing.*;
import java.awt.*;
class Screensaver {
private final static int FRAME_HEIGHT = 600;
private final static int FRAME_WIDTH = 600;
public static void main(String[] args) {
JFrame win;
Container contentPane;
win = new JFrame();
win.setSize(FRAME_WIDTH, FRAME_HEIGHT);
win.setVisible(true);
Component comp = new Component();
contentPane = (Container) win.getContentPane().add(comp);
}
}
class Component extends JComponent {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.magenta);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
g.fillRect(80, 350, 400, 250);
}
}
and about the color , you van create new Color and set the RED,GREEN,BLUE as you want , Try this :
g.setColor(new Color(red, green, blue));
The rectangle is drawn once, however every time the JFrames repaint() method is called it erases it and draws the basic Components. To add custom drawing in JFrames you have to override the paint method. Here I improved your code slightly to get you started down that path. As you can see you want to draw the box in the Paint method. I made a Container element that does your drawing and removed the background color, adding it to the paint method as well.
try this
import javax.swing.*;
import java.awt.*;
public class JavaApplication10 {
private final static int FRAME_HEIGHT = 600;
private final static int FRAME_WIDTH = 600;
public static void main(String[] args){
JFrame win = new JFrame();
win.setContentPane(new MyBoxContainer());
win.setSize(FRAME_WIDTH, FRAME_HEIGHT);
win.setVisible(true);
}
private static class MyBoxContainer extends Container {
#Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.MAGENTA);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
g.fillRect(80, 350, 400, 250);
}
}
}

Categories

Resources