Reputation: 470
I'm French so my English is quite bad but I have a real problem with java:
I'm trying to show an Image built manually with some fillRect
& co.
It works. Next, I want to update this image as a function of the text I enter in the text field. And there is the problem: it doesn't change anything, and if I manually rescale the window of the JFrame
, the image shows totally deformed or scaled badly.
I'm a beginner and I have difficulties with GUI, moreso when I want to couple it with Images.
Can you help me? Why doesn't it work as I want? This is my code below, a bit long but actually quite simple ! Thanks :)
I've changed it a bit, this is the 2e VERSION.
Now the problem s that I can't change a condition in order to modify the color of a simple rectangle, try "lol" in the entry field !
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.ImageIcon;
public class Fenetre extends JFrame {
private JFrame frame;
private JPanel container = new JPanel();
private JTextField jtf;
private JLabel label = new JLabel("Commandes ");
private JButton b = new JButton ("OK");
private Graphics graph;
private Image img;
private JLabel screen;
private boolean color;
/**
* Constructeur de l'objet
*/
public Fenetre(){
color = true;
frame = new JFrame();
frame.setTitle("Animation");
frame.setSize(1000, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
container.setBackground(Color.white);
container.setLayout(new BorderLayout());
JPanel top = new JPanel();
jtf = new JTextField();
jtf.setPreferredSize(new Dimension(800, 30));
b.addActionListener(new BoutonListener());
frame.setContentPane(top);
frame.setVisible(true);
paintComponent(graph);
screen = new JLabel( new ImageIcon(img));
top.add(screen);
top.add(label);
top.add(jtf);
top.add(b);
frame.setContentPane(top);
}
class BoutonListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
if(jtf.getText().equals("lol")) lol();
System.out.println("Entry : " + jtf.getText());
}
}
public void paintComponent(Graphics g)
{
if(img == null) {
img = frame.createImage(1000,300);
g = img.getGraphics();
}
g.setColor(Color.white);
g.fillRect(0,0,1000,300);
if(color) g.setColor(Color.orange); else g.setColor(Color.blue);
g.fillRect(8,25,200,100);
g.setColor(Color.green);
g.drawString("Text",10,10);
}
public void lol()
{
if(color) color = false; else color = true;
}
}
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.ImageIcon;
public class Fenetre extends JFrame {
private JPanel container = new JPanel();
private JTextField jtf;
private JLabel label = new JLabel("Commandes ");
private JButton b = new JButton ("OK");
private Graphics g;
private Image img;
private JLabel screen;
/**
* Constructeur de l'objet
*/
public Fenetre(){
this.setTitle("Animation");
this.setSize(1000, 400);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
container.setBackground(Color.white);
container.setLayout(new BorderLayout());
JPanel top = new JPanel();
jtf = new JTextField();
jtf.setPreferredSize(new Dimension(800, 30));
b.addActionListener(new BoutonListener());
this.setContentPane(top);
this.setVisible(true);
paint(g);
screen = new JLabel( new ImageIcon(img));
top.add(screen);
top.add(label);
top.add(jtf);
top.add(b);
this.setContentPane(top);
}
class BoutonListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
System.out.println("Entry : " + jtf.getText());
if(jtf.getText().equals("lol")) lol();
}
}
@Override
public void paint(Graphics g)
{
if(img == null) {
img = createImage(1000,300);
g = img.getGraphics();
}
g.setColor(Color.white);
g.fillRect(0,0,1000,300);
g.setColor(Color.orange);
g.fillRect(8,25,200,100);
g.setColor(Color.green);
g.drawString("Text",10,10);
}
@Override
public void update(Graphics g)
{
g.setColor(Color.blue);
g.fillRect(8,25,300,100);
}
public void lol()
{
g.setColor(Color.blue);
g.fillRect(8,25,200,100);
}
}
Upvotes: 2
Views: 1285
Reputation: 47608
I see several problems in your code:
g
member variable with the g
parameter of the paint
method. When lol
is called, g
is null
and you get a NullPointerException
Graphics
(only in really rare cases). Instead you override properly paintComponent()
and you use the Graphics
parameter to draw what you want. When you want to update the component, you call repaint()
paint
, but override paintComponent()
paint
of JFrame
. Use a dedicate component for that. No need to use a JLabel for that, a simple JComponent
is enough.JFrame
if you are not extending its functionality.revalidate()
Fix those issues and come back with another question if you still have problems.
You should probably consider reading this tutorial and the few next steps. It will show you basic examples of things similar to what you are trying to do.
EDIT: I took your V2 code and patched it as I could. This is very far from perfect but you should get the gist of how you can do this:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Fenetre extends JComponent {
private boolean color;
/**
* Constructeur de l'objet
*/
public Fenetre() {
color = true;
setPreferredSize(new Dimension(1000, 300));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.white);
g.fillRect(0, 0, 1000, 300);
if (color) {
g.setColor(Color.orange);
} else {
g.setColor(Color.blue);
}
g.fillRect(8, 25, 200, 100);
g.setColor(Color.green);
g.drawString("Text", 10, 10);
}
public void lol() {
if (color) {
color = false;
} else {
color = true;
}
repaint();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
initUI();
}
});
}
protected static void initUI() {
JFrame frame = new JFrame();
frame.setTitle("Animation");
frame.setSize(1000, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
JPanel container = new JPanel();
final JTextField jtf = new JTextField();
final Fenetre fenetre = new Fenetre();
JLabel label = new JLabel("Commandes ");
JButton b = new JButton("OK");
container.setBackground(Color.white);
container.setLayout(new BorderLayout());
JPanel top = new JPanel();
jtf.setPreferredSize(new Dimension(800, 30));
class BoutonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (jtf.getText().equals("lol")) {
fenetre.lol();
}
System.out.println("Entry : " + jtf.getText());
}
}
b.addActionListener(new BoutonListener());
top.add(fenetre);
top.add(label);
top.add(jtf);
top.add(b);
top.revalidate();
frame.setContentPane(top);
frame.setVisible(true);
}
}
Upvotes: 3
Reputation: 285405
Your Swing graphics programming has several significant problems, and I urge you to go through the tutorials to learn how to do this better. For example, you are
paint(...)
method. Instead you will want to draw in the paintComponent(...)
method override of a class derived from JComponent such as JPanel.Again, take a look at the tutorials on this -- you will not regret doing this, trust me.
edit -- too slow! 1+ to Guillaume
Upvotes: 3