make a JComponent opaque - java

I'm trying to make a JComponent opaque in the right border.
I want make a object with my specific characteristics so i'm using a JComponent that can be opaque
this is because I will make a library, and I don't want to use JPanel or JLabel
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
public class ProbadorCodigos {
JFrame Frame=new JFrame();
JComponent BORDEDE=new JComponent() {private static final long serialVersionUID = 2222L;};
public ProbadorCodigos() {
Frame.setSize(500, 500);
Frame.setResizable(false);
Frame.setUndecorated(false);
Frame.setLayout(null);
Frame.setLocationRelativeTo(null);
Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Frame.getContentPane().setBackground(Color.darkGray);
Format();
Action();
}
private void Format() {
BORDEDE.setBounds(Frame.getWidth()-100, 0, 100, Frame.getHeight());
BORDEDE.setOpaque(true);
BORDEDE.setVisible(true);
BORDEDE.setEnabled(true);
BORDEDE.setFocusable(true);
BORDEDE.setBackground(Color.red);
System.out.println(BORDEDE);
}
private void Action() {
Frame.add(BORDEDE);
}
public static void main(String[] args) {
ProbadorCodigos Ventana=new ProbadorCodigos();
Ventana.Frame.setVisible(true);
}
}
I don't know why it don't shows opaque, if I use a JLabel works so what I missing?
thanks for your advices and answers

My suggestion for general ease of solving your problem: use a JPanel. Until you show good reason for not using this as the basis for your class, it remains in my mind the best solution for your problem. Otherwise, you'll need some code like:
JComponent bordede = new JComponent() {
private static final long serialVersionUID = 2222L;
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
g.setColor(getBackground());
g.fillRect(0, 0, width, height);
}
};
Which again is not necessary if you simply used a JPanel.
Other problems with your code:
Your code does not comply with Java naming conventions and so will confuse other Java programmers.
You are using a null layout and setBounds(...) which will result in the creation of a rigid hard to enhance and debug GUI. You should avoid using this type of layout.

Related

Java JFrame not drawing lines in window

package Main;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
public class Main extends JFrame{
public static void main(String[] args) {
int width = 800;
int height = 600;
String title = "Test";
JFrame display = new JFrame();
display.setTitle(title);
display.setSize(width, height);
display.setVisible(true);
display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g) {
g.setColor(Color.white);
g.drawLine(0, 100, 800, 300);
getContentPane().setBackground(Color.black);
}
}
I'm using Java's JFrame. So this isn't recognising the paint method and cant figure out why. I've been looking on YouTube videos and having a look to see if anyone has had similar problems, however everything I've found doesn't seem to help the problem.
when i set the background colour in the main part, it works, bit in paint, it doesn't seem to do anything and leaves it blank.
Its a white line over a black background, so i should easily be able to see it.
Admittedly, I don't know much about Swing (I prefer JavaFX). However, it's clear that your Main class is a JFrame, so you should not make a new one within it. All of those methods you call on display are built in your current class. Basically, within your JFrame you made a new JFrame. However, your paint method was being called on the parent JFrame, which you never made visible. This solves your problem (you may have to fullscreen the window):
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
public class Main extends JFrame{
public static void main(String[] args) {
new Main();
}
public Main() {
int width = 800;
int height = 600;
String title = "Test";
setTitle(title);
setSize(width, height);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.WHITE);
g.drawLine(100, 100, 800, 300);
getContentPane().setBackground(Color.black);
}
}
You are creating an instance of JFrame with
JFrame display = new JFrame();
But the JFrame class has no logic to draw a white line on a black background. That logic is in your custom class Main. So instead, you should create an instance of Main:
JFrame display = new Main();
However, that change along still won't fix the problem because you are setting the background color of the "content pane" but trying to draw directly on the JFrame itself. The preferred solution here is to extend JPanel instead of JFrame and override its paintComponent() method. Then create an instance of your new class to use as the content pain:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainPanel extends JPanel{
public static void main(String[] args) {
int width = 800;
int height = 600;
String title = "Test";
JFrame display = new JFrame();
display.setTitle(title);
display.setSize(width, height);
display.setVisible(true);
display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
display.setContentPane(new MainPanel());
}
public MainPanel() {
setBackground(Color.black);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.white);
g.drawLine(0, 100, 800, 300);
}
}
Notes:
I call setBackground() in the constructor because it does not rely on the Graphics instance passed to paintComponent(). This also avoids the overhead of another function call for each render.
In paintComponent(), I call super.panitComponent(). This allows JPanel to clear the area to be painted and any other necessary initialization.

When i interchange the commented lines , i receive different output.

I am learning java abstract window toolkit and i am stuck in this code.When i interchange the commented line, the output changes.Any Explanation for both the cases will be appreciated.
import java.awt.*;
public class guibutton
{
public guibutton()
{
Frame f = new Frame("Panel Example");
Panel panel = new Panel();
panel.setBounds(40,80,200,200);
panel.setBackground(Color.gray);
f.add(panel);
f.setVisible(true); ////////////////this line
f.setLayout(null); /////////////////this line
f.setResizable(true);
f.setSize(400,400);
}
public static void main(String args[])
{
new guibutton();
}
}
This line:
f.setVisible(true);
renders your GUI in its current state, one where the JFrame's default BorderLayout is in force. Note that BorderLayout ignores the setBounds(...) method.
This line:
f.setLayout(null);
removes the JFrame contentPane's BorderLayout, and so your GUI is rendered without the layout, changing the positioning of the added JPanel -- the setBounds(...) method call here is respected.
If you call this after the GUI has been rendered, it won't have an effect, unless you do something that triggers the layout managers to re-layout the components, such as re-size the GUI.
Myself, I wouldn't use AWT but would use Swing, I'd draw the rectangle within the paintComponent method of a JPanel, using a Rectangle object. This way, I could monitor the mouse in relation to the rectangle, and change its state. For instance, try out this program, and see what happens to the rectangle when the mouse hovers over it:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class GuiButton2 extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private static final int RECT_X = 40;
private static final int RECT_Y = 80;
private static final int RECT_W = 200;
private static final Color DEFAULT_RECT_COLOR = Color.GRAY;
private static final Color HOVER_RECT_COLOR = Color.PINK;
private Rectangle rectangle = new Rectangle(RECT_X, RECT_Y, RECT_W, RECT_W);
private boolean hover = false;
public GuiButton2() {
setPreferredSize(new Dimension(PREF_W, PREF_H));
addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
// hover true if mouse is hovering over the rectangle
hover = rectangle.contains(e.getPoint());
repaint();
}
});
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// if hover true -- use hover color, otherwise use default color
Color c = hover ? HOVER_RECT_COLOR : DEFAULT_RECT_COLOR;
g2.setColor(c);
g2.fill(rectangle); // draw rectangle
}
private static void createAndShowGui() {
GuiButton2 mainPanel = new GuiButton2();
JFrame frame = new JFrame("GUI Button");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
Side note 1:
While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
Side note 2:
You will want to learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.

Java Swing Scroll through drawing

Im trying to add a JScrollpane to my JPanel. The problem is that the scrollpane doesn't recognize that my drawing is outside the frame. So how do I add the JScrollpane correctly?
Main class:
public MainFrame() extends JFrame{
public MainFrame() {
Container container = getContentPane();
container(new BorderLayout());
container.add(new JScrollPane(new Drawing()));
setSize(1280,720);
setVisible(true);
}
Drawing class:
public class Drawing() extends JPanel {
#Override
protected void paintComponent(Graphics g) {
g.drawLine(10, 100, 30000, 10);
}
}
There are a couple of errors in your code, let's step through each of them:
You're extending JFrame, and you should avoid it, see: Extends JFrame vs. creating it inside the program for more information about it. You're actually not changing its behavior so it's not needed to extend it.
For your JScrollPane to show the whole line, you need to change your window's size to be the same size of your line (as shown in this answer by #MadProgrammer).
Related to point 2, avoid the use of setSize(...) and instead override getPreferredSize(): See Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? for more information
You forgot to call super.paintComponent(...) method in your paintComponent() method.
Related to points 2, 3, you need to call pack() so Swing calculates the best preferred size for your component.
See this example:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class LongDraw {
private JFrame frame;
private Drawing drawing;
public static void main(String[] args) {
SwingUtilities.invokeLater(new LongDraw()::createAndShowGui);
}
private void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
drawing = new Drawing();
JScrollPane scroll = new JScrollPane(drawing);
frame.add(scroll);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
class Drawing extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawLine(10, 100, 3000, 10);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(3000, 500);
}
}
}
Which produces something similar to this:

Creating a simple custom JComponent in Java?

I want to start building my own customized JComponent's for a project at work. I have a simple example below that should just create a ball on the screen. (I found most of it on the internet) but it does provide a decent starting point. My question is why does this code not show the ball in my form? What have I done wrong?
Also what would be all of the basic methods that SHOULD be provided for a custom JComponent?
Code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class testBall {
public static void main(String[] args) {
new testBall();
}
public testBall() {
JPanel testPane = new JPanel();
testPane.setBackground(Color.white);
testPane.setLayout(new GridBagLayout());
testPane.add(new MyBall(30,30,10));
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(testPane);
frame.pack();
frame.setSize(500, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class MyBall extends JComponent
{
private static final long serialVersionUID = 1L;
public MyBall() { }
public MyBall(int x, int y, int diameter)
{
super();
this.setLocation(x, y);
this.setSize(diameter, diameter);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(0, 0, 100, 100);
}
}
Where I could find a list of all of the methods that should be overridden in a JComponent class? (I know there are ones that should always be included in JComponent.)
If I make an instance of this component in a class and need to change the color of the circle would I just call there repaint() method from that class?
You are adding the MyBall to testPane (which has a GridBagLayout) without specifying any constraints. (That is, your call to add() has no second parameter.) The default constraints are most likely not what you want. Try using BorderLayout for your test pane, as this uses BorderLayout.CENTER as the default, which is probably reasonable in your case:
testPane.setLayout(new BorderLayout());
This causes the ball to show up for me.
As for your second question, I think your class is fine as defined. The main method you want to implement is paintComponent() as you have. Sometimes it becomes necessary to override the get min/max/preferred size methods, but it really just depends on what you want the component to do. JComponent is not abstract, so you don't have to override anything if you don't want to. It provides a lot of functionality out of the box such as keyboard focus, pluggable look-and-feel, accessibility, etc. As long as you don't want to change any of that stuff, just leave it as is. Implement paintComponent() and the various get*Size() methods and be done with it. (You just kind of have to pick through the methods in the JavaDoc to see what is appropriate to override.)
The other option is to extend a subclass of JComponent, if there as a class that does something similar to what you want to do. For example, JPanel is often a good starting point for impelmenting your own container.
You were probably looking for something more concrete than 'it depends', but right now, if all you want is to draw a ball, then simply override the methods that deal with the rendering of the JComponent (paintCompentent(), and the get*Size() methods).
As a side note, you really should be using SwingUtilities.invokeLater() to create your Swing components on the Swing thread. See the section entitled "Swing's Threading Policy" at http://docs.oracle.com/javase/6/docs/api/javax/swing/package-summary.html.
Made some tweaks around your java class, the only change i did was add your new MyBall directly to the content pane of the JFrame, try to run this and you will see a red circle on your jframe
public class TestBall {
public static void main(String[] args) {
new TestBall();
}
public TestBall() {
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.getContentPane().add(new MyBall(30,30,10));
frame.pack();
frame.setSize(500, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class MyBall extends JComponent
{
private static final long serialVersionUID = 1L;
public MyBall() { }
public MyBall(int x, int y, int diameter)
{
super();
this.setLocation(x, y);
this.setSize(diameter, diameter);
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(0, 0, 100, 100);
}
}
Constructor: we just set location to the points, which are passed throught constuctor parameters. This is the place, in which this component will be located. The same way we set the size (width x height).
paintComponent: here we just paint some oval over passed graphics object.
The other part is just the test, which shows, that the component is correctly created and shown.

Paint method not being called

Im trying to simplify some basic code, an I've come across a small problem. I was under the impression that the paint method was called automatically, and i based that off every other basic program i have written. I dont get any erros, just the code doesn't work, and i cant call repaint() either.
Code:
public class Dynamic_Bg_Color{
JFrame frame;
public Dynamic_Bg_Color(){
frame = new JFrame("BG Color Changer");
}
public void paint(Graphics g1){
Graphics g = (Graphics)g1;
g.setColor(Color.pink);
g.fillRect(20,20,frame.getWidth()-20,100);
}
public static void main(String[] args){
Dynamic_Bg_Color d = new Dynamic_Bg_Color();
Dimension size = new Dimension(500,400);
d.frame.setPreferredSize(new Dimension(size));
d.frame.setMinimumSize(new Dimension(size));
d.frame.setMaximumSize(new Dimension(size));
d.frame.setLocationRelativeTo(null);
d.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
d.frame.setLayout(new FlowLayout());
d.frame.setVisible(true);
d.frame.getContentPane().setBackground(Color.cyan);
}
}
The paint method only gets called if it is an override, and the class extends another class where the paint method has meaning. Your class does not do this, and so your paint method is meaningless.
Having said that, I'm going to suggest that you don't overload paint but rather paintComponent(...) in a class that extends JComponent or one of its children. And most importantly, read the painting with Swing tutorial. Please start here.
As an aside, casting a Graphics object to a Graphics object achieves nothing. Perhaps you copied your code incorrectly and were meaning to cast it to a Graphics2D type?
I made the class extend JComponent, and added the override, but nothing has changed.
I don't see where you add the component to the frame.
Even if you did add the component to the frame is wouldn't paint because the default size of your component is (0, 0) so there is nothing to paint.
You also need to restructure your code. A JFrame variable does not belong to the component where you do custom painting. I suggest you read the section from the Swing tutorial on Custom Painting. It will show you:
How to do custom painting including how you specify a preferred size for your component
How to better structure your program, included executing your code on the Event Dispatch Thread
With minimal changes made the working code:
import javax.swing.*;
import java.awt.*;
public class Dynamic_Bg_Color extends JPanel{
JFrame frame;
public Dynamic_Bg_Color(){
frame = new JFrame("BG Color Changer");
}
public void paint(Graphics g1){
Graphics g = (Graphics2D)g1;
g.setColor(Color.pink);
g.fillRect(20,20,frame.getWidth()-20,100);
}
public static void main(String[] args){
Dynamic_Bg_Color d = new Dynamic_Bg_Color();
Dimension size = new Dimension(500,400);
d.setPreferredSize(new Dimension(size));
d.setMinimumSize(new Dimension(size));
d.setMaximumSize(new Dimension(size));
d.frame.add(d);
d.frame.setLocationRelativeTo(null);
d.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
d.frame.setLayout(new FlowLayout());
d.frame.pack();
d.frame.setVisible(true);
d.frame.getContentPane().setBackground(Color.cyan);
}
}
But, as others said, I don't suggest you use this cause it is very very bad structure of the program. And read the tutorial on painting, even if I think that Oracles tutorial on this is bad (frame.pack() just sets the size of the JFrame window as big as to hold the components it contains).
Heres the final working code. A few changes being it extended JPanel, setting the size of the JPanel, and adding the panel to the JFrame. Yes i know as everybody stated, this is not an optimal way of doing this, but for right now, it works.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Dynamic_Bg_Color extends JPanel{
private static final long serialVersionUID = 1L;
static Dimension size = new Dimension(500,400);
static JFrame frame;
public Dynamic_Bg_Color(){
setPreferredSize(size);
setBackground(Color.cyan);
addMouseListener(new Handler());
}
#Override
public void paintComponent(Graphics g){
System.out.println("Click");
super.paintComponent(g);
g.setColor(Color.blue);
g.fillRect(20,20,getWidth()-40,100);
g.setColor(Color.green);
g.fillRect(20,140,getWidth()-40,100);
g.setColor(Color.orange);
g.fillRect(20,260,getWidth()-40,100);
}
public static void main(String[] args){
Dynamic_Bg_Color d = new Dynamic_Bg_Color();
frame = new JFrame("BG Color Changer");
frame.setPreferredSize(new Dimension(size));
frame.setMinimumSize(new Dimension(size));
frame.setMaximumSize(new Dimension(size));
frame.setLayout(new FlowLayout());
frame.setLocationRelativeTo(null);
frame.add(d);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.cyan);
frame.setVisible(true);
}
public class Handler extends MouseAdapter{
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
if(x>= 20 && x<=getWidth()-40 && y>=20 && y<= 120){
frame.getContentPane().setBackground(Color.blue);
setBackground(Color.blue);
frame.setTitle("Blue");
}
if(x>= 20 && x<=getWidth()-40 && y>=140 && y<= 240){
frame.getContentPane().setBackground(Color.green);
setBackground(Color.green);
frame.setTitle("Green");
}
if(x>= 20 && x<=getWidth()-40 && y>=260 && y<= 360){
frame.getContentPane().setBackground(Color.orange);
setBackground(Color.orange);
frame.setTitle("Orange");
}
}
}
}

Categories

Resources