Background Color Issues - java

Can someone please assist me on why my background color of the frame is not being set. Is it possible to set the background color within the Paint() or must it be done in the JColor constructor
I am supposed to do the following for the BG color-
Write A GUI application that displays a single JButton and any background color you choose.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
/**
*
* #author Curtis
*/
public class JColor extends JFrame implements ActionListener
{
Font myFont = new Font("Playbill", Font.PLAIN, 28);
JButton myButton = new JButton("Click Me!");
Color bgColor = new Color(255, 97, 3);
Color txtColor = new Color(0, 0, 205);
String firstName = "Curtis";
String lastName = "Sizemore";
public JColor()
{
super("String Painting Fun");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout (new BorderLayout());
add(myButton, BorderLayout.SOUTH);
setDefaultLookAndFeelDecorated(true);
setBackground(Color.BLUE);
}
#Override
public void paint(Graphics e)
{
super.paint(e);
}
public static void main(String[] args)
{
final int TALL = 200;
final int WIDE = 250;
JColor frame = new JColor();
frame.setSize(WIDE, TALL);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e)
{
throw new UnsupportedOperationException("Not supported yet.");
}
}

Try calling it on the ContentPane instance (more info here)
public JColor() {
super("String Painting Fun");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
add(myButton, BorderLayout.SOUTH);
setDefaultLookAndFeelDecorated(true);
getContentPane().setBackground(Color.BLUE);//<- update
}

Related

How to print a image on a contentpane(JPanel) in java swing

In the main class Practice extends JFrame, there are three classes UpperPanel, CenterPanel and LowerPanel that extend JPanel.
I'm going to put buttons on UpperPanel and LowerPanel, and put a image on CenterPanel, and print it in one frame.
However, when the image prints out, three Panels aren't printed. and when three Panels print out, the image isn't printed.
I think the problem is setContentPane(new ImagePanel()); when I enter this code (in CenterPanel), Only images are printed. The rest of the panels(Upper, Center, Lower) are not output.
(I have created a separate image output class(ImagePanel extends JPanel), but It's okay to delete this class. But I want to use paintComponent(Graphics g).
I'm sorry for my poor English, and Thank you for reading it
please help me
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class Practice extends JFrame {
public int width = 480;
public int height = 720;
public Practice() {
setTitle("20201209");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(null);
setSize(width,height);
c.add(new UpperPanel());
c.add(new CenterPanel());
c.add(new LowerPanel());
setVisible(true);
}
class UpperPanel extends JPanel {
public UpperPanel() {
JPanel UpperPanel = new JPanel();
UpperPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 25));
UpperPanel.setBackground(Color.MAGENTA);
UpperPanel.setBounds(0, 0, 480, 100);
getContentPane().add(UpperPanel);
JButton btnEnlarge = new JButton("1");
btnEnlarge.setFont(new Font("궁서체", Font.PLAIN, 20));
btnEnlarge.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
UpperPanel.add(btnEnlarge);
JButton btnReduce = new JButton("2");
btnReduce.setFont(new Font("바탕체", Font.ITALIC, 20));
btnReduce.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
UpperPanel.add(btnReduce);
JButton btnFit = new JButton("3");
btnFit.setFont(new Font("돋움체", Font.BOLD, 20));
btnFit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
UpperPanel.add(btnFit);
}
}
class CenterPanel extends JPanel{
public CenterPanel() {
JPanel CenterPanel = new JPanel();
CenterPanel.setLayout(null);
CenterPanel.setBackground(Color.YELLOW);
CenterPanel.setBounds(0, 100, 480, 500);
CenterPanel.setOpaque(true);
getContentPane().add(CenterPanel);
setContentPane(new ImagePanel()); // when I enter this code, Only images are printed. The rest of the panels(Upper, Center, Lower) are not output
}
}
class ImagePanel extends JPanel { //this class is for image printing on CenterPanel
private ImageIcon icon = new ImageIcon("images/1771211.jpg");
private Image img = icon.getImage();
public void paintComponent(Graphics g) { //I want to use this code
super.paintComponent(g);
g.drawImage(img, 10, 110, this);
}
}
class LowerPanel extends JPanel {
public LowerPanel() {
JPanel LowerPanel = new JPanel();
LowerPanel.setLayout(null);
LowerPanel.setBackground(Color.BLACK);
LowerPanel.setBounds(0, 600, 480, 120);
getContentPane().add(LowerPanel);
getContentPane().add(new MyButton());
}
}
class MyButton extends JLabel{ //this class is for a Button on LowerPanel
MyButton(){
JButton btn = new JButton("4");
btn.setBounds(10, 610, 460, 100);
btn.setHorizontalAlignment(SwingConstants.CENTER);
btn.setVerticalAlignment(SwingConstants.CENTER);
btn.setFont(new Font("돋움체", Font.BOLD, 50));
btn.setBackground(Color.WHITE);
btn.setForeground(Color.RED);
btn.setOpaque(true);
getContentPane().add(btn);
}
}
public static void main(String[] args) {
new Practice();
}
}
Don't extend JFrame class unnecessarily
Don't use a null/AbsoluteLayout rather use an appropriate LayoutManager
Don't call setBounds() or setSize() on components, if you use a correct layout manager this will be handled for you
Call JFrame#pack() before setting the frame to visible
All Swing components should be called on the EDT via SwingUtilities.invokeLater
Here is a small example of what you want to achieve
TestApp.java:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestApp {
BufferedImage image;
public TestApp() {
createAndShowGui();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(TestApp::new);
}
private void createAndShowGui() {
JFrame frame = new JFrame("TestApp");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// load image
try {
image = ImageIO.read(new URL("https://i.stack.imgur.com/XNO5e.png"));
} catch (MalformedURLException ex) {
Logger.getLogger(TestApp.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(TestApp.class.getName()).log(Level.SEVERE, null, ex);
}
// upper panel
JPanel upperPanel = new JPanel(); // JPanels use FlowLayout by default
JButton button1 = new JButton("Button 1");
JButton button2 = new JButton("Button 2");
JButton button3 = new JButton("Button 3");
upperPanel.add(button1);
upperPanel.add(button2);
upperPanel.add(button3);
// center panel
JPanel centerPanel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(image.getWidth(), image.getHeight());
}
};
// lower panel
JPanel lowerPanel = new JPanel();
JButton button4 = new JButton("Button 4");
JButton button5 = new JButton("Button 5");
JButton button6 = new JButton("Button 6");
lowerPanel.add(button4);
lowerPanel.add(button5);
lowerPanel.add(button6);
frame.add(upperPanel, BorderLayout.NORTH); // JFrame uses BorderLayout by default
frame.add(centerPanel, BorderLayout.CENTER);
frame.add(lowerPanel, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
}

How to wait until JDialog is fully created

I need to calculate window decorations somehow. So I override JDialog's constructor. But when I call get_decoration_size() it sometimes returns wrong values. And my thought was: window creates later than get_decoration_size() executes(strange, because both in same thread and in same constructor). So I decided to sleep for a second, and it worked, and now decorations always valid.
My question is: is there a way to "join" to the creating process(wait until window is shown by setVisible(true))? If so, it must be something to replace unsafe_sleep(1000).
package swing.window;
import db.db;
import javax.swing.*;
import java.awt.*;
import static swing.util.*;
import static util.util.unsafe_sleep;
public class calc_decor extends JDialog {
{
//some initializations
setLayout(null);
setResizable(false);
JLabel label = new JLabel("Loading...");
add(label);
setxy(label, 3, 3);
fit(label);
setsize(this, label.getWidth() + 100, label.getHeight() + 100);
window_to_center(this);
setVisible(true);//trying to draw
unsafe_sleep(1000);//without that it looks like get_decoratoin_size()
//is called before setVisible(true)
db.sysdecor = get_decoration_size();//trying to get decorations
dispose();
}
private Dimension get_decoration_size() {
Rectangle window = getBounds();
Rectangle content = getContentPane().getBounds();
int width = window.width - content.width;
int height = window.height - content.height;
return new Dimension(width, height);
}
}
I had to assume a lot to create a runnable example.
Here's the result of your getDecorationSize method. The line didn't print until I closed the JDialog.
java.awt.Dimension[width=16,height=39]
And here's the code I used.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class JDialogTest implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new JDialogTest());
}
private JFrame frame;
#Override
public void run() {
frame = new JFrame("JDialog Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(
150, 100, 150, 100));
panel.setPreferredSize(new Dimension(400, 400));
JButton button = new JButton("Open JDialog");
button.addActionListener(new ButtonListener());
panel.add(button);
return panel;
}
public class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
new CalculateDecor(frame, "Spash Screen");
}
}
public class CalculateDecor extends JDialog {
private static final long serialVersionUID = 1L;
public CalculateDecor(JFrame frame, String title) {
super(frame, true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setTitle(title);
JPanel panel = new JPanel(new BorderLayout());
panel.setPreferredSize(new Dimension(200, 200));
JLabel label = new JLabel("Loading...");
label.setHorizontalAlignment(JLabel.CENTER);
panel.add(label);
add(panel);
pack();
setLocationRelativeTo(frame);
setVisible(true);
System.out.println(getDecorationSize());
}
private Dimension getDecorationSize() {
Rectangle window = getBounds();
Rectangle content = getContentPane().getBounds();
int width = window.width - content.width;
int height = window.height - content.height;
return new Dimension(width, height);
}
}
}

Animation Constructor not working in Java GUI

Hello I am new to Java GUI I made a second.java which is as below:
package theproject;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class second extends JPanel implements ActionListener {
private Timer animator;
private ImageIcon imageArray[];
private int delay=50, totalFrames=8, currentFreames=1;
public second()
{
imageArray= new ImageIcon[totalFrames];
System.out.println(imageArray.length);
for(int i=0; i<imageArray.length;i++)
{
imageArray[i]=new ImageIcon(i+1+".png");
System.out.println(i+1);
}
animator= new Timer(delay, this);
animator.start();
}
public void paintComponent(Graphics g )
{
super.paintComponent(g);
if(currentFreames<8)
{
imageArray[currentFreames].paintIcon(this, g, 0, 0);
currentFreames++;
System.out.println(currentFreames);
}
else{
currentFreames=0;
}
}
#Override
public void actionPerformed(ActionEvent arg0) {
repaint();
}
}
And a Gui calling the constructor second and output is not showing . Can you please guide me what should I do and the gui is given below:
package theproject;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.SwingConstants;
import javax.swing.JTextField;
public class Sav {
private JFrame frame;
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Sav window = new Sav();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Sav() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
textField = new JTextField();
textField.setBounds(10, 0, 261, 20);
frame.getContentPane().add(textField);
textField.setColumns(10);
JButton btnNewButton = new JButton("Submit");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
second s= new second();
frame.add(s);
}
});
btnNewButton.setBounds(273, -1, 89, 23);
frame.getContentPane().add(btnNewButton);
}
}
The gui has to basically call the constructor and which will showcase the animation on the screen If someone what i am doing wrong or if something that has to be done please let me know .
First, don't update the state within the paintComponent method, paint can occur for a number of reasons at any time, mostly without your interaction. Painting should simple paint the current state. In your ActionListener, you should advance the frame and make decisions about what should occur (like resetting the frame value)
Second, you never actually add second to anything, so it will never be displayed.
Third, you don't override getPreferredSize in second, so the layout managers will have no idea what size the component should be and will simply be assigned 0x0, making it as good as invisible as makes no difference
Fourth, you're using null layouts. This is going to make you life impossibly hard. Swing has been designed and optimised around the use of layout managers, they do important work in deciding how best to deal with differences in font metrics across different rendering systems/pipelines, I highly recommend that you take the time to learn how to use them
Fifthly, paintComponent has no business been public, no one should ever call it directly
Example
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
public class Sav {
private JFrame frame;
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Sav window = new Sav();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Sav() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
textField = new JTextField(20);
frame.getContentPane().add(textField, gbc);
JButton btnNewButton = new JButton("Submit");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
second s = new second();
frame.add(s, gbc);
frame.getContentPane().revalidate();
frame.pack();
frame.setLocationRelativeTo(null);
}
});
frame.getContentPane().add(btnNewButton, gbc);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public class second extends JPanel implements ActionListener {
private Timer animator;
private ImageIcon imageArray[];
private int delay = 50, totalFrames = 8, currentFreames = 1;
public second() {
imageArray = new ImageIcon[totalFrames];
for (int i = 0; i < imageArray.length; i++) {
imageArray[i] = new ImageIcon(getImage(i));
}
animator = new Timer(delay, this);
animator.start();
}
protected Image getImage(int index) {
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
FontMetrics fm = g2d.getFontMetrics();
g2d.dispose();
String text = Integer.toString(index);
int height = fm.getHeight();
int width = fm.stringWidth(text);
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g2d = img.createGraphics();
g2d.setColor(getForeground());
g2d.drawString(text, 0, fm.getAscent());
g2d.dispose();
return img;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(imageArray[0].getIconWidth(), imageArray[1].getIconHeight());
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
imageArray[currentFreames].paintIcon(this, g, 0, 0);
}
#Override
public void actionPerformed(ActionEvent arg0) {
currentFreames++;
if (currentFreames >= imageArray.length) {
currentFreames = 0;
}
repaint();
}
}
}
Your code is also not working. It increment the values of image set but do not displays the images
Works just fine for me...
imageArray[i]=new ImageIcon(i+1+".png"); will not generate any errors if the image can't be loaded for some reason (and it will load the images in the background thread, which is just another issue).
Instead, I would recommend using ImageIO.read instead, which will throw a IOException if the image can't be read for some reason, which is infinitely more useful. See Reading/Loading an Image for more details

Java Component not showing on startup

I have a Class that adds an ImageIcon in the East of a TextField if you pass it to that Class, it's working pretty good during runtime if I press a Button to change frames, but the Image is not showing up at the startup.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
public class TestStartFrame extends JFrame
{
/**
*
*/
private static final long serialVersionUID = 1L;
private JPanel contentPane;
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
TestStartFrame frame = new TestStartFrame();
frame.setVisible(true);
} catch (Exception e)
{
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public TestStartFrame()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JButton btnNewButton = new JButton("New button");
contentPane.add(btnNewButton, BorderLayout.CENTER);
btnNewButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
SecondFrame fr = new SecondFrame();
fr.setVisible(true);
try
{
int r = 250;
int g = 250;
int b = 250;
UIManager.put("control", new Color(r, g, b));
UIManager
.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
UIManager.put("control", new Color(r, g, b));
SwingUtilities
.updateComponentTreeUI(SecondFrame.contentPane);
} catch (Exception e1)
{
System.out.println(e1.getMessage());
}
dispose();
}
});
}
}
class SecondFrame extends JFrame
{
/**
*
*/
private static final long serialVersionUID = 1L;
public final static JPanel contentPane = new JPanel();
/**
* Create the frame.
*/
public SecondFrame()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout());
JTextField txt = new JTextField();
contentPane.add(txt, BorderLayout.CENTER);
txt = ClearImage.addImage(txt);
}
}
class ClearImage
{
public static JTextField addImage(final JTextField comp)
{
Image image = new BufferedImage(10, 25, BufferedImage.TYPE_INT_RGB);
Graphics graphics = image.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, 10, 25);
graphics.setColor(Color.LIGHT_GRAY);
graphics.fillOval(0, 7, 10, 10);
graphics.setColor(Color.GRAY);
graphics.drawLine(2, 9, 8, 15);
graphics.drawLine(2, 15, 8, 9);
JLabel lblClear = new JLabel(new ImageIcon(image));
comp.setLayout(new BorderLayout());
comp.add(lblClear, BorderLayout.EAST);
lblClear.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
lblClear.addMouseListener(new MouseAdapter()
{
#Override
public void mouseClicked(MouseEvent e)
{
comp.setText("");
}
});
return comp;
}
public static JTextField removeImage(final JTextField comp)
{
comp.removeAll();
return comp;
}
}
If I place the UI change before the Frame visible, I don't have that problem, could anyone explain me why is it that way?
Your problem is caused by the change of UI factory on the JTextField (this is triggered by the installation of the Nimbus L&F and the updateComponentTreeUI()).
When you do that the second call, you automatically uninstall the previous L&F and UI factory of the JTextField. By default, this is Metal L&F Text UI (MetalTextFieldUI) which extends BasicTextUI. This invokes the method javax.swing.plaf.basic.BasicTextUI.uninstallUI(JComponent) and its content is the following:
public void uninstallUI(JComponent c) {
// detach from the model
editor.removePropertyChangeListener(updateHandler);
editor.getDocument().removeDocumentListener(updateHandler);
// view part
painted = false;
uninstallDefaults();
rootView.setView(null);
c.removeAll();
LayoutManager lm = c.getLayout();
if (lm instanceof UIResource) {
c.setLayout(null);
}
// controller part
uninstallKeyboardActions();
uninstallListeners();
editor = null;
}
Notice the call c.removeAll() which basically removes your label from the hierarchy and hence causes the issue you are seeing.
Arguably, we could say that adding components to primitive Swing widgets is not ideal and this is not how they were intended to be used. I personally find that argument quite weak, but I know that many Swing lovers are found of it.
Simply make sure to do the update of the UI before adding your JLabel or extends JTextField and upon update of the UI, re-install your JLabel in the JTextField.
Small example (just to demo my explanation):
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class TestAddImageToTextField {
private static class MyJTextField extends JTextField {
#Override
public void updateUI() {
removeAll();
super.updateUI();
Image image = buildImage();
JLabel lblClear = new JLabel(new ImageIcon(image));
lblClear.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
MyJTextField.this.setText("");
}
});
setLayout(new BorderLayout());
add(lblClear, BorderLayout.EAST);
}
private Image buildImage() {
Image image = new BufferedImage(10, 25, BufferedImage.TYPE_INT_RGB);
Graphics graphics = image.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, 10, 25);
graphics.setColor(Color.LIGHT_GRAY);
graphics.fillOval(0, 7, 10, 10);
graphics.setColor(Color.GRAY);
graphics.drawLine(2, 9, 8, 15);
graphics.drawLine(2, 15, 8, 9);
return image;
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
TestAddImageToTextField frame = new TestAddImageToTextField();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private JComponent contentPane;
/**
* Create the frame.
*
* #throws UnsupportedLookAndFeelException
* #throws IllegalAccessException
* #throws InstantiationException
* #throws ClassNotFoundException
*/
public TestAddImageToTextField() throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 450, 300);
contentPane = (JComponent) frame.getContentPane();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
MyJTextField comp = new MyJTextField();
contentPane.add(comp);
frame.setVisible(true);
installNimbusLAF();
}
private void installNimbusLAF() throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
int r = 250;
int g = 250;
int b = 250;
UIManager.put("control", new Color(r, g, b));
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
UIManager.put("control", new Color(r, g, b));
SwingUtilities.updateComponentTreeUI(contentPane);
}
}

Image not appearing in jbutton with wordGen

The image isn't being painted when this is run with WordGen, how do i fix this?
When I run this without wordgen I can get the image to appear. I'm not sure what i'm doing wrong since i'm not getting any errors.
Any help is appreciated.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class tfot extends JComponent{
private static final long serialVersionUID = 1L;
public static void main(final String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
showGUI(args);
}
});
}
public static void showGUI(String[] args) {
JPanel displayPanel = new JPanel();
JButton okButton = new JButton("Did You Know?");
okButton.setFont(new Font("Times", Font.TRUETYPE_FONT, 100));
final JLabel jLab = new JLabel();
okButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
jLab.setText(wordGen());
}
});
JPanel content = new JPanel();
content.setLayout(new BorderLayout());
content.add(displayPanel, BorderLayout.CENTER);
content.add(okButton, BorderLayout.SOUTH);
content.add(jLab, BorderLayout.NORTH);
JFrame window = new JFrame("Window");
window.setContentPane(content);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(800, 600);
window.setLocation(400, 300);
window.setVisible(true);
}
#Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(Toolkit.getDefaultToolkit().getImage("Pictures/background1.png"), 0, 0, this);
}
public static String wordGen() {
String[] wordListOne = {"generic text","hi",};
int oneLength = wordListOne.length;
int rand1 = (int) (Math.random() * oneLength);
String phrase = wordListOne[rand1] + " ";
return phrase;
}
}
First...
Don't load resources or perform long running tasks within the paint methods, these may be called a number of times in quick succession. Instead, load the images before hand and paint them as needed...
public Tfot() {
setLayout(new BorderLayout());
try {
background = ImageIO.read(new File("pictures/background1.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (background != null) {
g.drawImage(background, 0, 0, this);
}
}
Generally, you are discouraged from overriding paint and instead should use paintComponent, lots of reasons, but generally, this is where the background is painted...
Second...
You need to add Tfot to something that is displayable, otherwise it will never be painted
JFrame window = new JFrame("Window");
window.setContentPane(new Tfot());
window.add(content);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(800, 600);
window.setLocation(400, 300);
window.setVisible(true);
Thrid...
JPanel by default is not transparent, you need to set it's opaque property to false
JPanel displayPanel = new JPanel();
displayPanel.setOpaque(false);
//...
JPanel content = new JPanel();
content.setOpaque(false);
Then it will allow what ever is below it to show up (ie, the background image)
Take a look at Painting in AWT and Swing, Performing Custom Painting and Reading/Loading an Image for more details
Fourth...
You need to learn the language basics for embarking on advance topics like GUI and custom painting, without this basic knowledge, this topics will bite you hard.
You need to declare background as a instance field of the class Tfot
private BufferedImage background;
public Tfot() {
Updated - Fully runnable example
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Tfot extends JComponent {
private static final long serialVersionUID = 1L;
public static void main(final String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
showGUI(args);
}
});
}
public static void showGUI(String[] args) {
JPanel displayPanel = new JPanel();
displayPanel.setOpaque(false);
JButton okButton = new JButton("Did You Know?");
okButton.setFont(new Font("Times", Font.TRUETYPE_FONT, 100));
final JLabel jLab = new JLabel();
okButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
jLab.setText(wordGen());
}
});
JPanel content = new JPanel();
content.setOpaque(false);
content.setLayout(new BorderLayout());
content.add(displayPanel, BorderLayout.CENTER);
content.add(okButton, BorderLayout.SOUTH);
content.add(jLab, BorderLayout.NORTH);
Tfot tfot = new Tfot();
tfot.setLayout(new BorderLayout());
tfot.add(content);
JFrame window = new JFrame("Window");
window.setContentPane(tfot);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(800, 600);
window.setLocation(400, 300);
window.setVisible(true);
}
private BufferedImage background;
public Tfot() {
try {
background = ImageIO.read(new File("Pictures/background1.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(background, 0, 0, this);
}
public static String wordGen() {
String[] wordListOne = {"generic text", "hi",};
int oneLength = wordListOne.length;
int rand1 = (int) (Math.random() * oneLength);
String phrase = wordListOne[rand1] + " ";
return phrase;
}
}

Categories