Problems extending JPanels - java

Hi I'm working on a problem and I'm having some issues working in Swing. I have no issues working with classes that extend either JFrame or JComponent, but when I try to use a class that I write that extends JPanel, it won't ever show up and nothing that I call on that panel shows up, including adding custom JComponents to it. What is the general procedure for creating a JPanel extendting class and then setting it as the content pane to use in a JFrame?

I (my personal view) can't see nothing wrong with extends JComponent as JComponent, JPanel, JLabel, more Inheritance versus composition, for example
import java.awt.*;
import javax.swing.*;
public class CustomComponent extends JFrame {
private static final long serialVersionUID = 1L;
public CustomComponent() {
setTitle("Custom Component Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(new CustomComponents());
pack();
setMinimumSize(getSize());// enforces the minimum size of both frame and component
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
CustomComponent main = new CustomComponent();
//main.display();
}
});
}
}
class CustomComponents extends JComponent {
private static final long serialVersionUID = 1L;
#Override
public Dimension getMinimumSize() {
return new Dimension(100, 100);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
#Override
public void paintComponent(Graphics g) {
int margin = 10;
Dimension dim = getSize();
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);
}
}

You should be added your class that extend the Jpanel to a container like JFrame.A class that extends the JPanel it not show any things because it a component not container.

Related

java JTextField paintComponent Method called repeatedly. Is that normal?

having subclassed JTextField, I noticed the paintComponent Method is called repeatedly (approximately every half-a-second) when the Field has Focus, even with no user interaction.
I read the Oracle article "Painting in AWT and Swing", but didn't find any enlightenment there.
Is this normal behaviour, or have a missed something?
Here's my example Proggy:
(positioning the Cursor in the 2nd - not subclassed - JTextField which has no logging, causes the subclassed one with logging to lose Focus which stops being repeatedly repainted)
import java.awt.*;
import javax.swing.*;
public class SwingPaintDemo2 extends JFrame {
public SwingPaintDemo2(final String title) {
super(title);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final Box box = new Box(BoxLayout.Y_AXIS);
box.add(new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(250, 200);
}
#Override
public void paintComponent(final Graphics g) {
super .paintComponent( g);
System.out.println("MyPanel.paintComponent......: " + g);
g.drawString("This is my custom Panel!", 10, 20);
}
});
box.add(new JTextField("JayTekst") {
#Override
public void paintComponent(final Graphics g) {
super .paintComponent( g);
System.out.println("JayTextField.paintComponent.: " + g);
}
});
box.add(new JTextField("JText"));
this.add(box);
this.pack();
this.setVisible(true);
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(() -> new SwingPaintDemo2("Swing Paint Demo"));
}
}
Of course it is normal. When the textfield has focus, you can see the cursor blinking which means you see the textfield with new a visual representation, which means paintComponent().

JPanel is not draw on JFrame

Linked to a previous question : I want to draw on panel. I have the following classes:
GMain.java
public class GMain{
static frmDashboard fDB;
public static void main(String[] args) {
fDB = new frmDashboard();
fDB.setTitle("Graphics Mate");
fDB.setVisible(true);
fDB.pack();
}
}
frmDashboard.java
public class frmDashboard extends javax.swing.JFrame {
public frmDashboard() {
initComponents();
Clear();
}
private void btnPlotActionPerformed(java.awt.event.ActionEvent evt) {
frmCPlot fCP = new frmCPlot();
fCP.setVisible(true);
fCP.pack();
}
}
frmCPlot.java
public class frmCPlot extends javax.swing.JFrame {
int W, H;
int N;
public frmCPlot() {
initComponents();
CPanel cp = new CPanel();
this.getContentPane().add(cp);
System.out.println("WW = " + cp.getWidth() +
" HH = " + cp.getHeight());
}
class CPanel extends JPanel{
int i, j;
public CPanel(){
setPreferredSize(new Dimension(400, 400));
setBackground(Color.WHITE);
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawLine(0, 0, this.getWidth(), this.getHeight());
}
}
}
The frmCPlot is displayed, but CPanel is not displayed. Not talking about the line. More, the output from the frmCPlot.java is:
*WW = 0 HH = 0*
I followed the instructions by the book. I tried to add a repaint in frmCPlot class, in CPanel class, but no use. Have any idea ?
It's never a good idea to extend a JFrame as it's a Top Level Component. This will just lead to more problems. You should, instead, create a class that extends a JPanel and add that to the a JFrame. A JPanel is good for when you want to group things together. Since you still have to have a JFrame somewhere in your program (or else it will display nothing) you'll have to make a variable instead and add the JPanel to it.
Try something like this
JFrame frame = new JFrame("My Frame");
frame.setSize(500, 500);
frame.getContentPane().add(new JPanel MyPanel);
frame.setVisible(true);

JPanel with JSlider not displaing the Graphics

All i have is a JPanel with a white background and the JSlider on the bottom, not displaying the square, i think i have made some mistake with the JPanel class but i can't figure it out. Just before i made another project with g.fillOval and it worked properly, i checked it out and every line of code seems the same, i am really confused.
public class Main00 {
public static void main(String[] args) {
Gui asd=new Gui();
asd.setVisible(true);
asd.setSize(500,400);
}
}
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
public class Gui extends JFrame {
private JSlider slider;
private DrawSquare square;
public Gui() {
super("square modificator");
setDefaultCloseOperation(EXIT_ON_CLOSE);
square = new DrawSquare();
square.setBackground(Color.WHITE);
slider = new JSlider(SwingConstants.HORIZONTAL, 0, 300,
square.getSide());
slider.setMajorTickSpacing(20);
slider.setPaintTicks(true);
add(square);
add(slider, BorderLayout.SOUTH);
slider.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
square.setSide(slider.getValue());
}
});
}
}
import java.awt.*;
import javax.swing.*;
public class DrawSquare extends JPanel {
private int side = 10;
public void paintComponents(Graphics g) {
super.paintComponents(g);
g.setColor(Color.RED);
g.fillRect(20, 20, side, side);
}
public void setSide(int side) {
this.side=(side>=0)?side:0;
repaint();
}
public Dimension getPrefferedSize(){
return new Dimension(200,200);
}
public Dimension getMinimumSize(){
return getPrefferedSize();
}
public int getSide(){
return side;
}
}
You're overriding paintComponents rather than the correct paintComponent. These two methods have drastically different effects, and the effect of the second is the one you want.
From the API:
paintComponents API entry: Paints each of the components in this container.
paintComponent API entry: Calls the UI delegate's paint method, if the UI delegate is non-null. We pass the delegate a copy of the Graphics object to protect the rest of the paint code from irrevocable changes
Again, you are interested in painting the component itself via its delegate and not in painting the components held by this component.

draw rectangle in Jpanel

I am trying to get my hands on GUI programming in java and wanted to draw a rectangle in Jpanel. Code does not give any error but I cannot get rectangle in the GUI. Can somebody please tell me what I am missing in the following code. I am sure it is pretty simple so please be gentle.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloWorldGUI2 {
private static class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
private static class RectDraw extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(230,80,10,10);
g.setColor(Color.RED);
g.fillRect(230,80,10,10);
}
}
public static void main(String[] args) {
JPanel content = new JPanel();
RectDraw newrect= new RectDraw();
JButton okButton= new JButton("OK");
JButton clearButton= new JButton("Clear");
ButtonHandler listener= new ButtonHandler();
okButton.addActionListener(listener);
clearButton.addActionListener(listener);
content.add(okButton);
content.add(clearButton);
content.add(newrect);
JFrame window = new JFrame("GUI Test");
window.setContentPane(content);
window.setSize(250,100);
window.setLocation(100,100);
window.setVisible(true);
}
}
Your newrect RectDraw's size is likely going to be quite small, probably [0, 0], since it has been added to a FlowLayout using JPanel and doesn't have a preferredSize set. Consider overriding its getPreferredSize() method and returning a suitable Dimension so that its drawing can be seen.
private static class RectDraw extends JPanel {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(230,80,10,10);
g.setColor(Color.RED);
g.fillRect(230,80,10,10);
}
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H); // appropriate constants
}
}
Also,
The paintComponent method should be protected, not public
Don't forget to use #Override before your method overrides.
Aim for much less code in the main method and more code in the "instance" world, not the static world.
Take care with your code formatting. Poor code formatting, especially misleading indentations, leads to silly errors.

Using Java's 2d Graphics Outside of the Main Class

I have a class called survival that contains the main method, an initializes the program. Instead of putting the code for graphics int this class, how can I move it into a new class which is separate from survival?
Here is Survival.java:
package survival;
import javax.swing.*;
public class Survival extends JFrame {
private static int applicationWidth = 1024;
private static int applicationHeight = 768;
public Survival() {
setTitle("Survival");
setResizable(false);
setSize(applicationWidth, applicationHeight);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new Survival();
}
}
Here is GraphicsDisplay.java:
package survival;
import java.awt.*;
import javax.swing.*;
public class GraphicsDisplay extends JPanel {
#Override public void paintComponent(Graphics g) {
g.fillOval(50, 50, 100, 100);
}
}
It seems like you can just add() an instance of GraphicsDisplay in the Survival constructor.
...
setResizable(false);
add(new GraphicsDisplay());
setSize(applicationWidth, applicationHeight);
...
In this case, GraphicsDisplay acts as a view of your implicit, circular model. You might look at how this example separates classes in the Model–View–Controller pattern.
Because GraphicsDisplay is a custom component that is rendered entirely by your program, consider overriding getPreferredSize() to define the panel's geometry. Then the enclosing frame can just use pack() without knowing anything about other display panels used in the game. This LissajousPanel is an example.
You have to extend the JPanel (JComponent) and override a paintComponent(Graphics g) method.
For instance,
public class MyPanel extends JPanel
{
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g); // suggestion of #kleopatra
}
}
In the Constructor add the component (JPanel) to the container (JFrame):
public Survival() {
setTitle("Survival");
setResizable(false);
setSize(applicationWidth, applicationHeight);
this.getContentPane().add( new GraphicsDisplay() );
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}

Categories

Resources