Weird BoxLayout painting - java

I was trying to dysplay an object line by line where each line is an object. Then I use a box Layout but when I do so only the top layer (which is the last object called) is drawed how can I fiw this ?
here is a minimal exemple :
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args) {
MainFrame frame = new MainFrame();
}
}
private class MainFrame extends JFrame {
public MainFrame(){
setSize(600,400);
setLocationRelativeTo(null);
setVisible(true);
setContentPane(new Container());
}
}
private class Container extends JPanel {
public Container(){
setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
for(int i =0;i<10;i++){
add(new Line());
}
}
}
private class Line extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.green);
g.fillRect(getX(),getY(),getWidth(),getHeight());
}
}
here is what I've got :
and what I've expected :
Some test (the blue rectangle in the paint method of the JBackPannel class) showed me that somewhere something is drawing a white canvas, but I don't know where and why ...
here is a link to a minimal exemple

Custom painting is always done relative to the component, not the components location in the parent panel.
So:
g.fillRect(getX(),getY(),getWidth(),getHeight());
should be:
g.fillRect(0, 0, getWidth(), getHeight());

Related

PaintComponent don't seem to get call or to show

My problem is really simple : I have this little program, and it just don't show the red box I'm trying to make :
Main
public class Main {
public static void main(String[] args) {
Affichage a = new Affichage();
a.setVisible(true);
}
}
Affichage :
import java.awt.*;
import javax.swing.*;
public class Affichage extends Frame{
public Affichage(){
setTitle("Exo 1 : Galerie");
setSize(1120,560);
Graphique graph = new Graphique();
this.add(graph);
}
}
Graphique :
import javax.swing.*;
import java.awt.*;
public class Graphique extends JComponent {
#Override
public void paintComponents(Graphics g) {
super.paintComponents(g);
Graphics pinceau = g.create();
pinceau.setColor(Color.RED);
pinceau.fillRect(100, 100, 200, 200);
System.out.println("test");
}
}
I bet it's ridicule but I can't find what it is, help me.
PS : yes the test don't get print too
Actually, don't extend JFrame as it is bad practice. Just make an instance of it. To paint, extend JPanel and override paintComponent.
JFrame f = new JFrame();
f.add(new MyPanel());
class MyPanel extends JPanel {
// other stuff
public void paintComponent(Graphics g) {
super.paintComponent(g);
// painting stuff.
}
}
And remember not to mix Swing and AWT components.
You are adding a Swing component (javax.swing.JComponent) to an AWT frame (java.awt.Frame). Noone will call the paintComponents() method, that's why you don't get any output or result. Extend from javax.swing.JFrame instead, so you have a Swing frame with a Swing component.

drawString not drawing text on window

I'm trying to make a test window with some text on it, when I run my code, it doesn't draw the string. I specified the color for it. Can anybody help me with this?
import javax.swing.*;
import java.awt.*;
class Main
{
public static void main(String[] args) {
DrawFrame f = new DrawFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
class DrawFrame extends JFrame
{
public DrawFrame(){
setTitle("For Aylin");
setSize(1280,720);
DrawPanel panel = new DrawPanel();
Container cp = getContentPane();
cp.add(panel);
}
}
class DrawPanel extends JPanel
{
public void paintComponents(Graphics g)
{
super.paintComponents(g);
g.setColor(Color.darkGray);
g.drawString("Hi", 100, 10);
}
}
You should override the JPanel's paintComponent method not its paintComponents method as they are for two very different purposes. The first paints the component itself (what you want) while the second gets the child components held by this parent to paint themselves.
Also remember to change the super call so that it matches, and to use the #Override annotation above the method.

Can't see child JPanel in JPanel in JFrame

I've created a JFrame.
Inside this JFrame, I've created a JPanel.
Inside this JPanel I've created another JPanel (lets call it "A").
I've drawn in "A" a rectangle, and wanted to create buttons using graphics.
There is no rectangle in my gui. I could see that the paintComponent() method inside "A" is not being invoked.
Code:
The JPanels: (the child JPanel is inner class)
public class MemoryPanel extends JPanel {
public MemoryPanel(){
setPreferredSize(new Dimension(350,448));
}
#Override
public void paintComponent(Graphics g) {
//POSITIONING
setLayout(new BorderLayout());
//CREATE MEMORY BUTTONS
MemButton a=new MemButton();
//Drawing Rectangles for Memory
add(a,BorderLayout.CENTER);
}
private class MemoryButton extends JPanel{
public MemoryButton(){
setLayout(null);
setPreferredSize(new Dimension(87,40));
}
#Override
public void paintComponent(Graphics g){
Graphics2D td= (Graphics2D)g;
td.drawRect(0, 0, 20, 20);
}
}
}
You should program the JButtons first in order for your graphics to work as buttons. I belive this post will help you with that:
Creating a custom button in Java
I you want a rectangle to be the background for your buttons you can draw it in your main panel and add the buttons on it. Try using different Layouts to mantain some order.
I've made a simple GUI to test your code and the rectangle appears correctly.
I made no relevant changes in the code that you posted.
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class SimpleJFrameProgram extends JFrame {
private static final long serialVersionUID = 1L;
public SimpleJFrameProgram() {
super("TEST");
initComponents();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
private void initComponents() {
MemoryPanel memoryPanel = new MemoryPanel();
this.add(memoryPanel);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
new SimpleJFrameProgram();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
I've applyed minor changes to your MemoryPanel: replaced MemButton by your MemoryButton and fill the rectangle in red to improve its visibility for the test. Without this last change, the rectangle appears too.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class MemoryPanel extends JPanel {
public MemoryPanel(){
setPreferredSize(new Dimension(350,448));
}
#Override
public void paintComponent(Graphics g) {
// POSITIONING
setLayout(new BorderLayout());
// CREATE MEMORY BUTTONS
MemoryButton a = new MemoryButton();
// Drawing Rectangles for Memory
add(a,BorderLayout.CENTER);
}
private class MemoryButton extends JPanel{
public MemoryButton(){
setLayout(null);
setPreferredSize(new Dimension(87,40));
}
#Override
public void paintComponent(Graphics g) {
Graphics2D td = (Graphics2D) g;
td.setColor(Color.red);
td.fillRect(0, 0, 20, 20);
}
}
}
This is the obtained result:
Maybe your problem is located on initializing the parent JFrame.
Changing the class name of MemoryButton fixed it.
I had another package with the same class name.

how to Combine MouseMotionListener and JPanel in java

I searched all over the Internet but could not find out why the circle is appears to be distorted beyond the middle of the JFrame(sorry,no image because i needed 10 reputation to post images).
I checked my code but found no errors.I'm a newbie to java GUI programming .
This is my code so far:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class test1 extends JPanel implements MouseMotionListener
{
private static final long serialVersionUID = -2068330714634802982L;
public int Mousex,Mousey;
public void init()
{
addMouseMotionListener(this);
}
public void mouseMoved(MouseEvent e)
{
Mousex=e.getX();
Mousey=e.getY();
repaint();
}
public void mouseDragged(MouseEvent e){}
public void paintComponent(Graphics g)
{
Graphics2D g2=(Graphics2D)g;
g2.setColor(Color.GREEN);
g2.fillOval(Mousex,Mousey,50,50);
}
public static void main(String[] args)
{
test1 t=new test1();
JFrame frame=new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1305,650);
frame.setLocationRelativeTo(null);
frame.getContentPane().add(t);
frame.setResizable(true);
frame.setVisible(true);
}
}
You need to call
t.init();
to register the MouseMotionListener. Also super.paintComponent(g); in the needs to be invoked in the paintComponent method to repaint the parent container otherwise the last rectangle wont be clearly visible.
You are never calling init() on your panel so you don't add the MouseMotionListener to the panel. Try adding
t.init();
after creating your panel object. Alternatively, add a constructor to your class that adds the MouseMotionListener instead, so it's adden right when you create an object of the class:
public test1 () {
addMouseMotionListener(this);
}

JButton subclass with custom shape shifts during repainting

I have just started working with Swing and am trying to draw a button with a custom shape, a triangle in this example. I called the JButton subclass 'ShiftingButton' in the following code because of its unusual behavior. When the mouse enters its region, it is repainted with an offset from its original position. Furthermore the shifted, offset version is drawn in addition to the original position so that both the original and shifted versions appear together. That is, when I run this code, the button is shown as a triangle along the left edge of the window. Then when I run the mouse over the button, a new triangle is drawn (in addition to the old one), shifted down and to the right by about 10 pixels. Resizing the window changes the offset of the phantom button from the original.
Experimenting with mouse clicks shows that only the original, correctly-positioned button is active. The region of the offset phantom button is not active.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.awt.Polygon;
public class ShiftingButton extends JButton implements ActionListener {
private Polygon shape;
public ShiftingButton () {
initialize();
addActionListener(this);
}
protected void initialize() {
shape = new Polygon();
setSize(120, 120);
shape.addPoint(0, 0);
shape.addPoint(0, 60);
shape.addPoint(90, 0);
setMinimumSize(getSize());
setMaximumSize(getSize());
setPreferredSize(getSize());
}
// Hit detection
public boolean contains(int x, int y) {
return shape.contains(x, y);
}
#Override
public void paintComponent (Graphics g) {
System.err.println("paintComponent()");
g.fillPolygon(shape);
}
protected void paintBorder(Graphics g) {
}
#Override
public void actionPerformed (ActionEvent ev) {
System.out.println("ShiftingButton ActionEvent!");
}
public static void main (String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
ShiftingButton button = new ShiftingButton();
panel.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
}
You failed to call super.paintComponent(g) inside the overridden paintComponent(...) method. Moreover, while overriding a method of the Base class, always try to keep the access specifier of the methods, the same, as much as possible. In this case it's protected and not public :-) Now function should be like this :
#Override
protected void paintComponent (Graphics g) {
System.err.println("paintComponent()");
super.paintComponent(g);
g.fillPolygon(shape);
}
EDIT 1 :
Moreover, since you are using a custom shape to be drawn, hence you again failed to specify the ContentAreaFilled property for this JButton in question, hence inside your constructor, you should write setContentAreaFilled(false), for it to work nicely. Though if this doesn't works (for reasons specified in the Docs), then you have to use the plain old Opaque property and set it to false for this JButton using setOpaque(false) :-)
Here is your code with modified changes :
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.awt.Polygon;
public class ShiftingButton extends JButton implements ActionListener {
private Polygon shape;
public ShiftingButton () {
setContentAreaFilled(false);
initialize();
addActionListener(this);
}
protected void initialize() {
shape = new Polygon();
setSize(120, 120);
shape.addPoint(0, 0);
shape.addPoint(0, 60);
shape.addPoint(90, 0);
}
#Override
public Dimension getPreferredSize() {
return (new Dimension(120, 120));
}
// Hit detection
public boolean contains(int x, int y) {
return shape.contains(x, y);
}
#Override
protected void paintComponent(Graphics g) {
System.err.println("paintComponent()");
super.paintComponent(g);
g.fillPolygon(shape);
}
protected void paintBorder(Graphics g) {
}
#Override
public void actionPerformed (ActionEvent ev) {
System.out.println("ShiftingButton ActionEvent!");
}
public static void main (String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
ShiftingButton button = new ShiftingButton();
panel.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
}

Categories