Java GridBagLayout: Rows are overlapping - java

I have a pretty simple JFrame. There are three main panels: the banner image at the top, a list of buttons on the left-hand side, and the main panel where the user will input his login information to access the rest of the application.
I'm using a GridBagLayout, and despite most people avoiding it like the plague, it's very straightforward to me, though it does add many lines of code into the mix. However I'm getting this strange problem where the top row (banner image) is overlapping the bottom row (button and login panels). I've checked and double-checked and looked all over the web for an answer but can't figure out what I'm doing wrong.
Basically the bottom row is vertically centered in the JFrame as a whole, and not in the second GridBag row as it should. And somehow the BannerPanel is being drawn on top of that, despite being added to the screen beforehand. I think it may have something to do with the way the BannerPanel works but I for one can't find a workaround.
This is what it looks like:
https://sphotos-a.xx.fbcdn.net/hphotos-snc7/375898_3720190211823_1073177291_n.jpg
This is what it SHOULD look like:
https://sphotos-a.xx.fbcdn.net/hphotos-ash4/314993_3720190291825_1429407717_n.jpg
Here's my code:
public class LoginWindow extends JFrame implements ActionListener {
final static String unlockCode = "unlock";
ArrayList <User> userlist = new ArrayList <User> ();
User user = null;
// The visible parts of the window
GridBagConstraints gridbag;
JLabel inputLabel, errorLabel, lockedLabel, unlockLabel;
JTextField usernameField, unlockField;
JPasswordField passwordField;
JPanel inputPanel, usernamePanel, passwordPanel, unlockPanel;
public static void main(String[] args) {
LoginWindow win = new LoginWindow ();
win.userlist.add(new User ("username", "password", true));
}
public LoginWindow () {
setTitle("Login");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setBackground(Color.GRAY);
setSize(640, 480);
setResizable(false);
resetGridbag();
// This is where I declare all the JLabels, JPanels, etc
inputLabel = new JLabel ("Secure Login");
inputLabel.setFont(new Font ("SansSerif", Font.BOLD, 24));
inputLabel.setForeground(Color.WHITE);
JLabel usernameLabel = new JLabel ("Username ");
usernameLabel.setForeground(Color.WHITE);
usernameField = new JTextField (10);
usernameField.setActionCommand("Login");
usernameField.addActionListener(this);
usernamePanel = new JPanel ();
usernamePanel.setBackground(Color.GRAY);
usernamePanel.add(usernameLabel);
usernamePanel.add(usernameField);
JLabel passwordLabel = new JLabel ("Password ");
passwordLabel.setForeground(Color.WHITE);
passwordField = new JPasswordField (10);
passwordField.setActionCommand("Login");
passwordField.addActionListener(this);
passwordPanel = new JPanel ();
passwordPanel.setBackground(Color.GRAY);
passwordPanel.add(passwordLabel);
passwordPanel.add(passwordField);
errorLabel = new JLabel ("");
errorLabel.setForeground(Color.WHITE);
lockedLabel = new JLabel ("You've been locked out!");
lockedLabel.setForeground(Color.WHITE);
unlockLabel = new JLabel ("Unlock Code");
unlockLabel.setForeground(Color.WHITE);
unlockField = new JTextField (10);
unlockField.setActionCommand("Unlock");
unlockField.addActionListener(this);
unlockPanel = new JPanel ();
unlockPanel.setBackground(Color.GRAY);
unlockPanel.add(unlockLabel);
unlockPanel.add(unlockField);
JLabel newPassword = new JLabel ("Request a new password");
newPassword.setForeground(Color.WHITE);
JPanel optionPanel = new JPanel ();
optionPanel.setBackground(Color.GRAY);
optionPanel.add(newPassword);
inputPanel = new JPanel ();
inputPanel.setBackground(Color.GRAY);
inputPanel.setLayout(new GridBagLayout ());
// Now I'm going to add them all to the screen
GridBagLayout gbl = new GridBagLayout ();
gbl.columnWeights = new double [] {0.0f, 1.0f};
gbl.rowWeights = new double [] {0.0f, 1.0f};
setLayout(gbl);
gridbag.gridwidth = 2;
gridbag.gridy = 0;
gridbag.fill = GridBagConstraints.HORIZONTAL;
add(new BannerPanel (), gridbag);
gridbag.gridy = 1;
gridbag.gridwidth = 1;
gridbag.anchor = GridBagConstraints.NORTHWEST;
add(optionPanel, gridbag);
gridbag.gridx++;
gridbag.anchor = GridBagConstraints.CENTER;
add(inputPanel, gridbag);
redraw();
setVisible(true);
}
public void resetGridbag () {
gridbag = new GridBagConstraints ();
gridbag.anchor = GridBagConstraints.CENTER;
gridbag.gridx = gridbag.gridy = 0;
}
public void reset () {
inputPanel.removeAll();
resetGridbag();
validate();
repaint();
}
public void redraw () {
reset();
if (user == null || !user.locked()) {
inputPanel.add(inputLabel, gridbag);
gridbag.gridy++;
inputPanel.add(new JLabel (" "), gridbag);
gridbag.gridy++;
inputPanel.add(usernamePanel, gridbag);
gridbag.gridy++;
inputPanel.add(passwordPanel, gridbag);
gridbag.gridy++;
inputPanel.add(new JLabel (" "), gridbag);
gridbag.gridy++;
inputPanel.add(errorLabel, gridbag);
}
else {
inputPanel.add(lockedLabel, gridbag);
gridbag.gridy++;
inputPanel.add(unlockPanel, gridbag);
gridbag.gridy++;
inputPanel.add(errorLabel, gridbag);
errorLabel.setText("");
}
validate();
repaint();
}
public void actionPerformed (ActionEvent e) {
String button = e.getActionCommand();
if (button.equals("Login")) {
boolean usernameMatch = false;
boolean passwordMatch = false;
for (int i = 0; i < userlist.size(); i++) {
if (usernameField.getText().equals(userlist.get(i).username())) {
usernameMatch = true;
user = userlist.get(i);
}
if (new String (passwordField.getPassword()).equals(userlist.get(i).password()))
passwordMatch = true;
}
passwordField.setText("");
if (usernameMatch) {
if (passwordMatch) {
user.unlock();
//new MainWindow ();
dispose();
}
else {
user.loginFail();
if (!user.locked())
errorLabel.setText("Login unsuccessful. " +
user.loginAttempts() + " attempts left!");
else
redraw();
}
}
else
errorLabel.setText("Login unsuccessful.");
validate();
}
else if (button.equals("Unlock")) {
if (unlockField.getText().equals(unlockCode)) {
errorLabel.setText("");
user.unlock();
redraw();
}
else {
errorLabel.setText("Invalid unlock code.");
validate();
}
unlockField.setText("");
}
}
}
class BannerPanel extends JPanel {
Image image;
int width = 0, height = 0;
double ratio = 0.0;
public BannerPanel () {
try {
image = ImageIO.read(BannerPanel.class
.getClassLoader().getResourceAsStream("banner.png"));
}
catch (Exception e) { e.printStackTrace(); }
}
#Override
protected void paintComponent (Graphics g) {
super.paintComponent(g);
ratio = (double) getWidth() / image.getWidth(null);
width = getWidth();
height = getImageHeight();
setSize(width, height);
if (image != null) {
g.drawImage(image, 0, 0, width, height, this);
}
}
public int getImageHeight () {
return (int) (image.getHeight(null) * ratio);
}
}
public class User {
String username = "";
String password = "";
boolean superuser = false;
int loginAttempts = 3;
public User (String username, String password, boolean superuser) {
this.username = username;
this.password = password;
this.superuser = superuser;
}
public String username () {
return username;
}
public String password () {
return password;
}
public boolean superuser () {
return superuser;
}
public int loginAttempts () {
return loginAttempts;
}
public void loginFail () {
if (loginAttempts > 0)
loginAttempts--;
}
public boolean locked () {
return (loginAttempts == 0);
}
public void lock () {
loginAttempts = 0;
}
public void unlock () {
loginAttempts = 3;
}
}

The height of your BannerPanel is based on the height of the image (height = getImageHeight();). However, this is the height the BannerPanel is drawn at, not the height it asks for. You need to override getPreferredSize() to deliver the correct desired height based on the image and ratio - otherwise the layout will be made assuming 0 height for the BannerPanel.
Edit
I think the problem is that you're trying to create a component with a fixed ratio between height and width, while deferring the width to the parent container. This creates a situation where you have to wait for the layout to be performed once before you can know the component's preferred size. Performing these calculations in paintComponent will work, as you've experienced, by waiting for layout, resizing, drawing, waiting for layout and drawing again. It's not ideal - you do have to perform the layout twice, but there's no intrinsic need to do the drawing twice. I don't think Swing gives you enough control to reliably avoid this, but there are more idiomatic ways to do it! For example, you can override setBounds to change the preferred height based on the actual width:
#Override
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
int pWidth = getPreferredSize().width;
setPreferredSize(new Dimension(pWidth, width / 2));
}

Jacob Raihle had the right idea, however it didn't work for me.
What did work was adding a call to setPreferredSize() to paintComponent(), right next to setSize().
Apparently setSize() allows the entire image to be drawn while setPreferredSize() tells the rest of the layout how much space it's taking up. Would be great to have it all in one method without having to override but hey, what are you gonna do?
Here's the new code for my BannerPanel object:
class BannerPanel extends JPanel {
Image image;
int width = 0, height = 0;
double ratio = 0.0;
public BannerPanel () {
try {
image = ImageIO.read(BannerPanel.class
.getClassLoader().getResourceAsStream("banner.png"));
}
catch (Exception e) { e.printStackTrace(); }
}
#Override
protected void paintComponent (Graphics g) {
super.paintComponent(g);
ratio = (double) getWidth() / image.getWidth(null);
width = getWidth();
height = getImageHeight();
setPreferredSize(new Dimension (width, height));
setSize(width, height);
if (image != null) {
g.drawImage(image, 0, 0, width, height, this);
}
}
public int getImageHeight () {
return (int) (image.getHeight(null) * ratio);
}
}

Related

How to keep the other components in front when redrawing a JPanel used as a background?

I've looked all over and I can only find cases of people using their custom JPannel to draw an image over another image but what I'm trying to do is draw a component over the JPannel and no matter what I try it always moves the JPannel when it draws the next frame. It feels like ther must be a way to override the meathod that draws it on front and allows you to draw it in the very back but there was none that i could find.
public class MovingBackgroundDemo {
private JToggleButton button = new JToggleButton("Button");
private JFrame frame = new JFrame();
private int framewidth =frame.getWidth();
private int frameheight =frame.getHeight();
public MovingBackgroundDemo() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addComponentListener(new ComponentAdapter()
{
public void componentResized(ComponentEvent evt) {
framewidth =frame.getWidth();
frameheight =frame.getHeight();
button.setBounds(framewidth/2 - framewidth/14 - framewidth/6,frameheight/6, framewidth/6, frameheight / 12);
}
});
frame.add(button);
frame.add(new AnimatingPanel());
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private class AnimatingPanel extends JPanel {
private static final int DIM_W = 350;
private static final int DIM_H = 350;
private static final int INCREMENT = 10;
private BufferedImage backgroundImage;
private Image runnerImage;
private int dx1, dy1, dx2, dy2;
private int srcx1, srcy1, srcx2, srcy2;
private int IMAGE_WIDTH;
public AnimatingPanel() {
initImages();
initImagePoints();
Timer timer = new Timer(40, new ActionListener() {
public void actionPerformed(ActionEvent e) {
moveBackground();
repaint();
}
});
timer.start();
FlowLayout layout = (FlowLayout)getLayout();
layout.setHgap(0);
layout.setVgap(0);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
g.drawImage(backgroundImage, dx1, dy1, dx2, dy2, srcx1, srcy1,
srcx2, srcy2, this);
g.drawImage(runnerImage, 0, 0, getWidth(), getHeight(), this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(350, 350);
}
private void initImagePoints() {
dx1 = 0;
dy1 = 0;
dx2 = DIM_W;
dy2 = DIM_H;
srcx1 = 0;
srcy1 = 0;
srcx2 = DIM_W;
srcy2 = DIM_H;
}
private void initImages() {
try {
File icoen = new File("the picture");
runnerImage = ImageIO.read(icoen);
File icon = new File("the other one");
backgroundImage = ImageIO.read(icon);
IMAGE_WIDTH = backgroundImage.getWidth();
System.out.println(IMAGE_WIDTH);
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void moveBackground() {
if (srcx1 > IMAGE_WIDTH) {
srcx1 = 0 - DIM_W;
srcx2 = 0;
} else {
srcx1 += INCREMENT;
srcx2 += INCREMENT;
}
}
}
public static void main(String[] args) {
new MovingBackgroundDemo();
}
}
Any tips?
This:
frame.add(button);
frame.add(new AnimatingPanel());
Should be:
JPanel animationPanel = new AnimatingPanel();
animationPanel.add(button);
frame.add(animationPanel);
The first code is trying to add the two components (button and panel) to the same exact layout position in the frame. That won't work (properly, or in some cases, at all).

How to slowly change object color from one to another?

I am trying to achieve a scenario where the color of an object changes slowly from one color to another color.
I have the initial color as targetColor and final color as updateColor. The changingSpeed variable is set to 5.
The mechanism that I have to use is
Use getRed(), getGreen(), getBlue() to obtain the red, green and blue color
Compute the difference of color of target bytargetColor–color = [ dr dg db]
Normalize [ dr dg db] by dividing the norm of the vector [ dr dg db] T(Beware of div by zero)
Multiply it by changingSpeed to control the speed in changing the color
Update the color to color + [ dr’ dg’ db’ ]
So far, i have been able to make the following code:
dr=targetColor.getRed()-updateColor.getRed();
dg=targetColor.getGreen()-updateColor.getGreen();
db=targetColor.getBlue()-updateColor.getBlue();
double nrml= Math.sqrt((dr*dr)+(dg*dg)+(db*db));
dr=dr/nrml;
dg=dg/nrml;
db=db/nrml;
How to execute the 4th and 5th steps?
Can please anyone specify how to do this via code example?
Also please check if the above code is correct.
Here is an example the fades the background as you move from component to component:
import java.awt.*;
import java.awt.event.*;
import java.util.Hashtable;
import java.util.ArrayList;
import javax.swing.*;
public class Fader
{
// background color when component has focus
private Color fadeColor;
// steps to fade from original background to fade background
private int steps;
// apply transition colors at this time interval
private int interval;
// store transition colors from orginal background to fade background
private Hashtable backgroundColors = new Hashtable();
/*
* Fade from a background color to the specified color using
* the default of 10 steps at a 50 millisecond interval.
*
* #param fadeColor the temporary background color
*/
public Fader(Color fadeColor)
{
this(fadeColor, 10, 50);
}
/*
* Fade from a background color to the specified color in the
* specified number of steps at the default 5 millisecond interval.
*
* #param fadeColor the temporary background color
* #param steps the number of steps to fade in the color
*/
public Fader(Color fadeColor, int steps)
{
this(fadeColor, steps, 50);
}
/*
* Fade from a background color to the specified color in the
* specified number of steps at the specified time interval.
*
* #param fadeColor the temporary background color
* #param steps the number of steps to fade in the color
* #param intevral the interval to apply color fading
*/
public Fader(Color fadeColor, int steps, int interval)
{
this.fadeColor = fadeColor;
this.steps = steps;
this.interval = interval;
}
/*
* Add a component to this fader.
*
* The fade color will be applied when the component gains focus.
* The background color will be restored when the component loses focus.
*
* #param component apply fading to this component
*/
public Fader add(JComponent component)
{
// Get colors to be used for fading
ArrayList colors = getColors( component.getBackground() );
// FaderTimer will apply colors to the component
new FaderTimer( colors, component, interval );
return this;
}
/*
** Get the colors used to fade this background
*/
private ArrayList getColors(Color background)
{
// Check if the color ArrayList already exists
Object o = backgroundColors.get( background );
if (o != null)
{
return (ArrayList)o;
}
// Doesn't exist, create fader colors for this background
ArrayList colors = new ArrayList( steps + 1 );
colors.add( background );
int rDelta = ( background.getRed() - fadeColor.getRed() ) / steps;
int gDelta = ( background.getGreen() - fadeColor.getGreen() ) / steps;
int bDelta = ( background.getBlue() - fadeColor.getBlue() ) / steps;
for (int i = 1; i < steps; i++)
{
int rValue = background.getRed() - (i * rDelta);
int gValue = background.getGreen() - (i * gDelta);
int bValue = background.getBlue() - (i * bDelta);
colors.add( new Color(rValue, gValue, bValue) );
}
colors.add( fadeColor );
backgroundColors.put(background, colors);
return colors;
}
class FaderTimer implements FocusListener, ActionListener
{
private ArrayList colors;
private JComponent component;
private Timer timer;
private int alpha;
private int increment;
FaderTimer(ArrayList colors, JComponent component, int interval)
{
this.colors = colors;
this.component = component;
component.addFocusListener( this );
timer = new Timer(interval, this);
}
public void focusGained(FocusEvent e)
{
alpha = 0;
increment = 1;
timer.start();
}
public void focusLost(FocusEvent e)
{
alpha = steps;
increment = -1;
timer.start();
}
public void actionPerformed(ActionEvent e)
{
alpha += increment;
component.setBackground( (Color)colors.get(alpha) );
if (alpha == steps || alpha == 0)
timer.stop();
}
}
public static void main(String[] args)
{
// Create test components
JComponent textField1 = new JTextField(10);
textField1.setBackground( Color.YELLOW );
JComponent textField3 = new JTextField(10);
JComponent textField4 = new JTextField(10);
JComponent button = new JButton("Start");
JComponent checkBox = new JCheckBox("Check Box");
JFrame frame = new JFrame("Fading Background");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.getContentPane().add(textField1, BorderLayout.NORTH );
frame.getContentPane().add(button, BorderLayout.SOUTH );
frame.getContentPane().add(textField3, BorderLayout.WEST );
frame.getContentPane().add(textField4, BorderLayout.EAST );
frame.getContentPane().add(checkBox);
// Gradual Fading (using defaults)
// Fader fader = new Fader( new Color(155, 255, 155) );
Fader fader = new Fader( new Color(155, 255, 155), 10, 50 );
fader.add( textField1 );
fader.add( textField3 );
fader.add( checkBox );
// Instant Fading
fader = new Fader( new Color(255, 155, 155), 1, 1 );
fader.add( textField4 );
fader.add( button );
frame.pack();
frame.setVisible( true );
}
}
It uses a Timer to update the backgrounds at the specified interval. It then just interpolates between the two color based on the number of steps desired.
Look at this example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Test {
public static void main(String args[]) {
final JFrame frame = new JFrame();
frame.setBounds(100, 100, 300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// set some random initial color
final Component comp = frame.getContentPane();
comp.setBackground(new Color(
(float) Math.random(),
(float) Math.random(),
(float) Math.random()));
frame.setVisible(true);
final Timer timer = new Timer(50, new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
final Color targetColor = new Color(30,40,50);
final int changingSpeed = 5;
final Color currentColor = comp.getBackground();
// step 1
int r = currentColor.getRed();
int g = currentColor.getGreen();
int b = currentColor.getBlue();
// step 2
double dr = targetColor.getRed() - r;
double dg = targetColor.getGreen() - g;
double db = targetColor.getBlue() - b;
// step 3
double norm = Math.sqrt(dr*dr+dg*dg+db*db);
if (norm < .001) {
((Timer)(evt.getSource())).stop();
return;
}
dr /= norm;
dg /= norm;
db /= norm;
// step 4
dr *= Math.min(changingSpeed, norm);
dg *= Math.min(changingSpeed, norm);
db *= Math.min(changingSpeed, norm);
// step 5
r += dr;
g += dg;
b += db;
comp.setBackground(new Color(r,g,b));
frame.repaint();
}
});
timer.start();
}
}
A few things to note:
Use a timer to fire the updates. This ensures, they are done in the EventThread, what is mandatory for manipulating Swing GUIs.
Test the norm for beeing very small. This means, your delta is near zero and you should stop updating the color.
Use the minimum of the norm and your changing speed. If your changing speed is high enough, your color will alternate around the target color and your delta will swap the sign forever and the process doesn't terminate. So if your delta is smaller than your changing speed, use the delta!
Don't forget to call repaint, when you are done with manipulating the color.
Yea, instead of using the for loop in line
while(i<=10);
you can actually use your changing speed. Meanwhile your changingSpeed should
be an array of length 3 because the different offset of colors interval i.e
dr, dg, db so that they can be taking care of independently.
like this...
int [] changingSpeed(int []Offset){
int loop = 5;
// 5 means the color should be change 5 times
int [] changeSpeed = new int[3];
changeSpeed[0]= offset[0]/loop;
changeSpeed[1]= offset[1]/loop;
changeSpeed[2]= offset[2]/loop;
return changeSpeed;
}
// your update method will now look like this
updateColor(int [] changeSpeed) throws AWTException{
int dr = changeSpeed[0];
int dg = changeSpeed[1];
int db = changeSpeed[2];
Robot slow = new Robot();
int i=0;
int f= loop; // the number of time you want the color to change
while(i<=f){
slow.delay(1000)
//sleep will sleep for 1000ms
setColor(targetColor.getRed() + dr/10, targetColor.getGreen(),targetColor.getBlue());
setColor(targetColor.getRed(), targetColor.getGreen() + (dg/10),targetColor.getBlue());
setColor(targetColor.getRed(), targetColor.getGreen(),targetColor.getBlue() + db/10);
i++;
}
}
I wouldnt rely on a specific delay time to compute the next step in an animation as this will certainly provide different execution times in different machines, although it might not be a relevant difference.
Instead of a changing speed factor your could use a long representing the animation total time and use a Thread (or another multithreading mecanism) to control the animation lifecycle (such as calculating how much time has passed since the last repaint and whats the percentage of completion for the next iteration).
I don't know if I followed your math instructions.
I created a Swing GUI so i could watch the transition from one color to another.
The Reset Colors button generates a random starting color and a random finishing color. The Start button transforms the bottom panel from the starting color to the finishing color. Each transformation moves about 5 values in either the red, green, or blue dimension, with a delay of 300 milliseconds.
I tended to watch the numbers change, rather than the color. I wanted to make sure that the transformation was fairly even.
Anyway, here's the code. You can use this to model other Swing GUI's. I put all the classes together in one file so I could paste the code here. You should separate the classes into separate files.
package com.ggl.testing;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ColorChangeTest implements Runnable {
private static final Insets normalInsets = new Insets(10, 10, 0, 10);
private Color currentColor;
private Color targetColor;
private ColorPanel changingColorPanel;
private ColorPanel currentColorPanel;
private ColorPanel targetColorPanel;
private JLabel changingLabel;
private JLabel currentLabel;
private JLabel targetLabel;
public static void main(String args[]) {
SwingUtilities.invokeLater(new ColorChangeTest());
}
#Override
public void run() {
JFrame frame = new JFrame("Color Change Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
mainPanel.add(createColorPanel(), BorderLayout.NORTH);
mainPanel.add(createChangingPanel(), BorderLayout.CENTER);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createColorPanel() {
JPanel colorPanel = new JPanel();
setNewColors();
JPanel currentPanel = new JPanel();
currentPanel.setLayout(new BorderLayout());
JPanel currentLabelPanel = new JPanel();
currentLabelPanel.setLayout(new BorderLayout());
JLabel startLabel = new JLabel("Starting Color");
startLabel.setHorizontalAlignment(JLabel.CENTER);
currentLabelPanel.add(startLabel, BorderLayout.NORTH);
currentLabel = new JLabel(getColorString(currentColor));
currentLabel.setHorizontalAlignment(JLabel.CENTER);
currentLabelPanel.add(currentLabel, BorderLayout.SOUTH);
currentPanel.add(currentLabelPanel, BorderLayout.NORTH);
currentColorPanel = new ColorPanel(100, 100, currentColor);
currentPanel.add(currentColorPanel, BorderLayout.CENTER);
colorPanel.add(currentPanel);
JPanel targetPanel = new JPanel();
targetPanel.setLayout(new BorderLayout());
JPanel targetLabelPanel = new JPanel();
targetLabelPanel.setLayout(new BorderLayout());
JLabel finishLabel = new JLabel("Finishing Color");
finishLabel.setHorizontalAlignment(JLabel.CENTER);
targetLabelPanel.add(finishLabel, BorderLayout.NORTH);
targetLabel = new JLabel(getColorString(targetColor));
targetLabel.setHorizontalAlignment(JLabel.CENTER);
targetLabelPanel.add(targetLabel, BorderLayout.SOUTH);
targetPanel.add(targetLabelPanel, BorderLayout.NORTH);
targetColorPanel = new ColorPanel(100, 100, targetColor);
targetPanel.add(targetColorPanel, BorderLayout.CENTER);
colorPanel.add(targetPanel);
colorPanel.add(createButtonPanel());
return colorPanel;
}
private JPanel createButtonPanel() {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridBagLayout());
int gridy = 0;
JButton resetButton = new JButton("Reset Colors");
resetButton.addActionListener(new ResetColorsListener(this));
addComponent(buttonPanel, resetButton, 0, gridy++, 1, 1, normalInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JButton startButton = new JButton("Start");
startButton.addActionListener(new ColorChangeListener(this));
addComponent(buttonPanel, startButton, 0, gridy++, 1, 1, normalInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
return buttonPanel;
}
private JPanel createChangingPanel() {
JPanel changingPanel = new JPanel();
changingPanel.setLayout(new BorderLayout());
changingLabel = new JLabel(getColorString(currentColor));
changingLabel.setHorizontalAlignment(JLabel.CENTER);
changingPanel.add(changingLabel, BorderLayout.NORTH);
changingColorPanel = new ColorPanel(300, 200, currentColor);
changingPanel.add(changingColorPanel, BorderLayout.CENTER);
return changingPanel;
}
public void setChangingColorLabelText(Color color) {
changingLabel.setText(getColorString(color));
}
public void setNewColors() {
currentColor = getRandomColor();
targetColor = getRandomColor();
}
public void displayNewColors() {
currentLabel.setText(getColorString(currentColor));
targetLabel.setText(getColorString(targetColor));
changingLabel.setText(getColorString(currentColor));
currentColorPanel.setColor(currentColor);
targetColorPanel.setColor(targetColor);
changingColorPanel.setColor(currentColor);
}
public Color getCurrentColor() {
return currentColor;
}
public Color getTargetColor() {
return targetColor;
}
public ColorPanel getChangingColorPanel() {
return changingColorPanel;
}
private Color getRandomColor() {
return new Color((float) Math.random(), (float) Math.random(),
(float) Math.random());
}
private String getColorString(Color color) {
int r = color.getRed();
int g = color.getGreen();
int b = color.getBlue();
return "(" + r + ", " + g + ", " + b + ")";
}
private void addComponent(Container container, Component component,
int gridx, int gridy, int gridwidth, int gridheight, Insets insets,
int anchor, int fill) {
GridBagConstraints gbc = new GridBagConstraints(gridx, gridy,
gridwidth, gridheight, 1.0D, 1.0D, anchor, fill, insets, 0, 0);
container.add(component, gbc);
}
public class ColorPanel extends JPanel {
private static final long serialVersionUID = -2894328511698328096L;
private Color color;
public ColorPanel(int width, int height, Color color) {
this.color = color;
this.setPreferredSize(new Dimension(width, height));
}
public void setColor(Color color) {
this.color = color;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(color);
g.fillRect(0, 0, getWidth(), getHeight());
}
}
public class ResetColorsListener implements ActionListener {
private ColorChangeTest colorChangeTest;
public ResetColorsListener(ColorChangeTest colorChangeTest) {
this.colorChangeTest = colorChangeTest;
}
#Override
public void actionPerformed(ActionEvent event) {
colorChangeTest.setNewColors();
colorChangeTest.displayNewColors();
}
}
public class ColorChangeListener implements ActionListener {
private ColorChangeTest colorChangeTest;
public ColorChangeListener(ColorChangeTest colorChangeTest) {
this.colorChangeTest = colorChangeTest;
}
#Override
public void actionPerformed(ActionEvent event) {
ColorChange colorChange = new ColorChange(colorChangeTest);
new Thread(colorChange).start();
}
}
public class ColorChange implements Runnable {
private static final long sleepTime = 300L;
private double r, g, b, dr, dg, db;
private int tr, tg, tb, cr, cg, cb;
private ColorChangeTest colorChangeTest;
public ColorChange(ColorChangeTest colorChangeTest) {
this.colorChangeTest = colorChangeTest;
}
#Override
public void run() {
calculateColorChange();
sleep(sleepTime);
while (calculateNextColor()) {
sleep(sleepTime);
}
setColor(colorChangeTest.getTargetColor());
}
private void calculateColorChange() {
double increment = 5D;
// step 1
r = cr = colorChangeTest.getCurrentColor().getRed();
g = cg = colorChangeTest.getCurrentColor().getGreen();
b = cb = colorChangeTest.getCurrentColor().getBlue();
// step 2
tr = colorChangeTest.getTargetColor().getRed();
tg = colorChangeTest.getTargetColor().getGreen();
tb = colorChangeTest.getTargetColor().getBlue();
dr = tr - cr;
dg = tg - cg;
db = tb - cb;
// step 3
double d = Math.sqrt(dr * dr + dg * dg + db * db);
int steps = (int) (d / increment);
dr /= (double) steps;
dg /= (double) steps;
db /= (double) steps;
setColor(new Color(cr, cg, cb));
}
private boolean calculateNextColor() {
// step 5
r += dr;
g += dg;
b += db;
if (isFinished()) {
return false;
} else {
setColor(new Color(round(r), round(g), round(b)));
return true;
}
}
private boolean isFinished() {
return isColorFinished(cr, tr, round(r))
|| isColorFinished(cg, tg, round(g))
|| isColorFinished(cb, tb, round(b));
}
private int round(double value) {
return (int) Math.round(value);
}
private boolean isColorFinished(int original, int target, int current) {
boolean isFinished = false;
if (current < 0 || current > 255) {
isFinished = true;
} else if ((target >= original) && (current >= target)) {
isFinished = true;
} else if ((target <= original) && (current <= target)) {
isFinished = true;
}
return isFinished;
}
private void setColor(final Color color) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
colorChangeTest.getChangingColorPanel().setColor(color);
colorChangeTest.setChangingColorLabelText(color);
}
});
}
private void sleep(long sleepTime) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
}
}
}
}
In order to achieve the act of slowness, it might be a good idea to use the instance of Robot class.
//Method to obtain the offset of the color
static int [] getColorOffset(Color initial, Color final){
int [] colorOffset = new int[3];
colorOffset[0]= final.getRed()-initial.getRed();
colorOffset[1] = final.getGreen()-initial.getGreen();
colorOffset[2]= final.getBlue()-initial.getBlue();
return colorOffset;
}
updateColor(int [] colorOffset) throws AWTException{
int dr = colorOffset[0];
int dg = colorOffset[1];
int db = colorOffset[2];
Robot slow = new Robot();
int i=0;
while(i<=10){
slow.delay(1000)
//sleep will sleep for 1000ms
setColor(targetColor.getRed() + dr/10, targetColor.getGreen(),targetColor.getBlue());
setColor(targetColor.getRed(), targetColor.getGreen() + (dg/10),targetColor.getBlue());
setColor(targetColor.getRed(), targetColor.getGreen(),targetColor.getBlue() + db/10);
i++;
}
}
public static void main(String args[]) throws AWTException{
Color initial = Color.black;
Color final = Color,white;
int [] colorOffset = getColorOffset(initial, final);
updateColor(colorOffset);
}

How to change the set color in a for loop?

My circles change color, but while the smallest one always remains red, the largest does not remain blue. Whenever I attempt to change my code from what it is now, all circles become the same color, and just change shade when the slider is moved. I would like there to just be more shades in between the red and blue as the slider increases. Could you please explain the changes I need to make? I understand everything I'm doing, except the color changing part.
public class SliderLab1 extends JFrame {
JSlider slider;
GPanel graphicsPanel;
public SliderLab1() {
super("Slider/Shapes Demo");
setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE );
JPanel outerPanel = new JPanel();
graphicsPanel = new GPanel(); //for shapes
JPanel sliderPanel = new JPanel();
setup(sliderPanel);
outerPanel.add(graphicsPanel);
outerPanel.add(sliderPanel);
add(outerPanel);
pack();
setVisible(true);
}
private void setup(JPanel p) {
slider = new JSlider(
JSlider.VERTICAL,4,20,8);
slider.setMinorTickSpacing(1);
slider.setMajorTickSpacing(4);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.addChangeListener( new SLstn() );
p.add(slider);
}
private class SLstn implements ChangeListener {
public void stateChanged(ChangeEvent e) {
int x = slider.getValue();
System.out.println(x);
graphicsPanel.setCount(x);
graphicsPanel.repaint();
}
}
private class GPanel extends JPanel {
int count = 8;
int size = 400;
int stepSize = (int)size/count;
public GPanel() {
setPreferredSize(
new Dimension(size,size));
setBackground(Color.BLACK);
}
public void setCount(int n) {
count=n;
stepSize = (int)size/count;
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setStroke(new BasicStroke(3) );
for(int i = count; i>=0; i--){
Color myC = new Color(((255/stepSize)*(stepSize-i)), 0, (255/stepSize)*i );
g.setColor(myC);
for (int j = 0; j <= count; j++) {
g.drawOval(0,(size-(stepSize*i)),stepSize*i,stepSize*i);
g.fillOval(0,(size-(stepSize*i)),stepSize*i,stepSize*i);
}
}
}
}
public static void main(String[] args) {
new SliderLab1();
}
}
Simply replace:
Color myC = new Color(((255/stepSize)*(stepSize-i)), 0, (255/stepSize)*i );
by:
final Color myC = new Color(((255 / count) * (count - i)), 0, (255 / count) * i);
You don't want to work with stepSize at this point, using count should do the trick :)
I hope it helps!

Image gets disappeared in the vertical scrollpane view port

duke.png ->
arrowToLeft.gif ->
arrowToRight.gif ->
I need a UI where I want to depict a network device's graphical representation in Swing. For this, I am just loading multiple images and overlap them one by one to show the current state of the device. I have to support zooming for this view. The zoom code looks like this.
public class LayeredPaneTest{
private JLayeredPane layeredPane;
private JScrollPane scrollPane;
private static double MIN_ZOOM_VALUE = 0.60; // 1.0;
private static double MAX_ZOOM_VALUE = 2.0;
private static final int LAYER1 = 0;
private static final int LAYER2 = 1;
private static final int LAYER3 = 3;
private double scaleFactor = 1.0;
private JInternalFrame internalFrame =
new JInternalFrame("LayeredPaneTest",false, false, false, false);
public LayeredPaneTest(){
loadView();
}
public JInternalFrame getView(){
return internalFrame;
}
private void loadView(){
((javax.swing.plaf.basic.BasicInternalFrameUI)internalFrame.getUI())
.setNorthPane(null);
internalFrame.setBorder(null);
internalFrame.getContentPane().add(buildCenterPane());
internalFrame.setSize(new Dimension(200, 200));
internalFrame.setLocation(0, 0);
internalFrame.setResizable(false);
internalFrame.setVisible(true);
}
private JPanel buildCenterPane(){
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
layeredPane = new JLayeredPane();
Position shelfPosition = new Position(0,0,200,200);
setLayeredPaneSize(shelfPosition);
JLabel label = getImageLabel(getImage("duke.png"),
new Position(0,0,100,100));
layeredPane.add(label, Integer.valueOf(LAYER1));
label = getImageLabel(getImage("arrowToLeft.gif"),
new Position(100,100,50,50));
layeredPane.add(label, Integer.valueOf(LAYER2));
label = getImageLabel(getImage("arrowToRight.gif"),
new Position(50,50,50,50));
layeredPane.add(label, Integer.valueOf(LAYER3));
scrollPane = new JScrollPane(layeredPane);
panel.add(scrollPane, BorderLayout.CENTER);
panel.add(getSliderPane(), BorderLayout.SOUTH);
return panel;
}
private Image getImage(String key){
InputStream is = this.getClass().getResourceAsStream(key);
try {
return ImageIO.read(is);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private void setLayeredPaneSize(Position shelfPosition){
int width = (int)(shelfPosition.getWidth() * scaleFactor + 10);
int height = (int)(shelfPosition.getHeight() * scaleFactor + 10);
layeredPane.setPreferredSize(new Dimension(width,height));
}
public void zoom(double factor){
if (factor < MIN_ZOOM_VALUE)
factor = MIN_ZOOM_VALUE;
else if (factor > MAX_ZOOM_VALUE)
factor = MAX_ZOOM_VALUE;
scaleFactor = factor;
Position shelfPosition = new Position(0,0,200,200);
setLayeredPaneSize(shelfPosition);
scrollPane.getViewport().repaint();
scrollPane.repaint();
scrollPane.getViewport().revalidate();
scrollPane.revalidate();
}
private JLabel getImageLabel(Image image, Position position) {
position = position.moveInRatio(scaleFactor);
ImageLabel label = new ImageLabel(new ImageIcon(image), position);
label.setOpaque(false);
label.setBounds(position.getLeft(),
position.getTop(),position.getWidth(),position.getHeight());
return label;
}
private JPanel getSliderPane(){
JPanel outer = new JPanel();
outer.setLayout(new FlowLayout());
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
final JSlider slider = new JSlider((int) (MIN_ZOOM_VALUE * 100),
(int) (MAX_ZOOM_VALUE * 100), 100);
slider.setMajorTickSpacing(1);
slider.setMinorTickSpacing(1);
double sliderValue = scaleFactor * 100.0;
slider.setValue((int) sliderValue);
slider.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
scaleFactor = slider.getValue() / 100.0;
zoom(scaleFactor);
}
});
panel.add(slider, BorderLayout.CENTER);
outer.add(panel);
return outer;
}
public static void main(String...strings){
JFrame frame = new JFrame("FrameDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new LayeredPaneTest().getView(),
BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
static class Position{
private final int left,top,width,height;
Position(int x1, int y1, int x2, int y2){
this.left = x1;
this.top = y1;
this.width = x2;
this.height = y2;
}
public int getLeft() {
return left;
}
public int getTop() {
return top;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}
private class ImageLabel extends JLabel{
private static final long serialVersionUID = 6152144095443433296L;
private ImageIcon image;
private Position position;
public ImageLabel(ImageIcon image, Position position){
super(image);
this.image = image;
this.position = position;
}
public void paintComponent(Graphics g) {
int newX = (int)(position.getLeft() * scaleFactor);
int newY = (int)(position.getTop() * scaleFactor);
Graphics2D g2 = (Graphics2D)g;
int newW = (int)(position.getWidth() * scaleFactor);
int newH = (int)(position.getHeight() * scaleFactor);
setBounds(newX, newY, newW, newH);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawImage(image.getImage(), 0, 0, newW, newH, null);
}
}
}
But the problem here is, when I zoom in once and zoom out, some of the images disappear. Any idea why it behaves like this?
Following are the steps to reproduce the bug;
a. Drag the slider bar to the maximum,
b. Witness the image being expanded to maximum and the scroll bar is introduced,
c. Now few portion of the image is hidden,
d. Now drag the slider bar to minimum.
e. The hidden portion of the image disappears.
You do not honor the paint chain by calling super.XXX implementation of overridden paintComponent method like so:
#Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
//do the rest of the painting here
}
As the docs clearly state:
if you do not invoker super's implementation you must honor the opaque
property, that is if this component is opaque, you must completely
fill in the background in a non-opaque color. If you do not honor the
opaque property you will likely see visual artifacts.
Also note the #Override annotation to make sure I am overriding the correct method, and by default paintComponent is protected keep it that way as you dont want to expose this method to other classes they should use repaint()

trouble adding background image to my jpanel, can't find error, I didn't understood the error also

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test
{
public static void panel1()
{
JFrame frame=new JFrame("#b's metric calculator");
//Color b=new Color(0,150,255);
//JPanel Cr=new JPanel();
final JTextField textField = new JTextField(10);
//textField.setBackgound(0,255,220);
JButton button=new JButton("Enter Centimeter");
final JTextField textFiel= new JTextField("Your result will be here",20);
String[] list = {"cm-inch","cm-meter","cm-feet","inch-feet"};
/*The <string> added below is to avoid "unchecked or unsafe operations” warning in Java ,
if passing integer set it <Integer>*/
final JComboBox<String> list1 = new JComboBox<String>(list);
list1.setSelectedIndex(0);
JButton submit=new JButton("Submit");
submit.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//textFiel.setText(textField.getText());
//following command converts textfild value to integer
int centi=Integer.parseInt(textField.getText());
//----------------------------------------------------
//double area = 3.14*radius*radius;
int cb = list1.getSelectedIndex();//to get the index of selected item(eg. 0,1,2..)
if(cb==0)
{
Double inch = centi/2.54;
//following command converts double to string
String out = Double.toString(inch);
//-----------------------------------------
textFiel.setText(out);
}
else if(cb==1)
{
Double meter = centi/100.00;
String out = Double.toString(meter);
textFiel.setText(out);
}
else if(cb==2)
{
Double feet = centi/30.48;
String out = Double.toString(feet);
textFiel.setText(out);
}
else
{
Double feet = centi/12.00;
String out = Double.toString(feet);
textFiel.setText(out);
}
}
});
//c.setBackground(b);
frame.add(new Cr());
Cr.add(button);
Cr.add(textField);
Cr.add(list1);
Cr.add(submit);
Cr.add(textFiel);
button.setPreferredSize(new Dimension(150,30));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400,300);
frame.setVisible(true);
JOptionPane.showMessageDialog(frame,"Welcome \n enter centimeter in blank box\n Select your choice\n then press submit");
}
class Cr extends JPanel{
ImageIcon image = new ImageIcon("C:/Users/Public/Pictures/Sample Pictures/Desert.jpg");
public void paint( Graphics g ) {
Dimension d = getSize();
for( int x = 0; x < d.width; x += image.getIconWidth() )
for( int y = 0; y < d.height; y += image.getIconHeight() )
g.drawImage( image.getImage(), x, y, null, null );
super.paint(g);
}
}
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run() {
panel1();
}
});
}
}
problem code is this section,it started when i tried to add image to panel.
class Cr extends JPanel{
ImageIcon image = new ImageIcon("C:/Users/Public/Pictures/Sample Pictures/Desert.jpg");
public void paint( Graphics g ) {
Dimension d = getSize();
for( int x = 0; x < d.width; x += image.getIconWidth() )
for( int y = 0; y < d.height; y += image.getIconHeight() )
g.drawImage( image.getImage(), x, y, null, null );
super.paint(g);
}
}
can you pls help me guys ,pls say which all i have to change.
it says error non-static variable can't be referenced from a static context. thks in advance.
thks to every one and 'vedant1811' for the layout idea ,'mKorbel' for overriding paint and 'nIcE cOw' for putting my code on center ,i used it now i made my program finally working. thks
My final code
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test extends JPanel{
public Test() {
setOpaque(false);
setLayout(new FlowLayout());
}
public static void main(String[] args) {
JFrame frame = new JFrame("#b's metric calculator");
final JTextField textField = new JTextField(10);
JButton button = new JButton("Enter Centimeter");
final JTextField textFiel = new JTextField("Your result will be here", 20);
String[] list = {"cm-inch", "cm-meter", "cm-feet", "inch-feet"};
/*The <string> added below is to avoid "unchecked or unsafe operations” warning in Java ,
if passing integer set it <Integer>*/
final JComboBox<String> list1 = new JComboBox<String>(list);
list1.setSelectedIndex(0);
JButton submit = new JButton("Submit");
Test Cr = new Test();
submit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//textFiel.setText(textField.getText());
//following command converts textfild value to integer
int centi = Integer.parseInt(textField.getText());
//----------------------------------------------------
//double area = 3.14*radius*radius;
int cb = list1.getSelectedIndex();//to get the index of selected item(eg. 0,1,2..)
if (cb == 0) {
Double inch = centi / 2.54;
//following command converts double to string
String out = Double.toString(inch);
//-----------------------------------------
textFiel.setText(out);
} else if (cb == 1) {
Double meter = centi / 100.00;
String out = Double.toString(meter);
textFiel.setText(out);
} else if (cb == 2) {
Double feet = centi / 30.48;
String out = Double.toString(feet);
textFiel.setText(out);
} else {
Double feet = centi / 12.00;
String out = Double.toString(feet);
textFiel.setText(out);
}
}
});
frame.add(Cr);
Cr.add(button);
Cr.add(textField);
Cr.add(list1);
Cr.add(submit);
Cr.add(textFiel);
button.setPreferredSize(new Dimension(150, 30));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setVisible(true);
JOptionPane.showMessageDialog(frame, "Welcome \n enter centimeter in blank box\n Select your choice\n then press submit");
}
public void paint(Graphics g)
{
// Loads the background image and stores in img object.
Image img = Toolkit.getDefaultToolkit().getImage("C:\\Users\\Administrator\\Documents\\JAVA\\My java programs\\hd_wall_11493.jpg");
// Draws the img to the BackgroundPanel.
g.drawImage(img,0,0,getSize().width,getSize().height,this);
super.paint(g);
}
}
don't want to comment something
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Test {
public Test() {
JFrame frame = new JFrame("#b's metric calculator");
//Color b=new Color(0,150,255);
//JPanel Cr=new JPanel();
final JTextField textField = new JTextField(10);
//textField.setBackgound(0,255,220);
JButton button = new JButton("Enter Centimeter");
final JTextField textFiel = new JTextField("Your result will be here", 20);
String[] list = {"cm-inch", "cm-meter", "cm-feet", "inch-feet"};
/*The <string> added below is to avoid "unchecked or unsafe operations” warning in Java ,
if passing integer set it <Integer>*/
final JComboBox<String> list1 = new JComboBox<String>(list);
list1.setSelectedIndex(0);
JButton submit = new JButton("Submit");
submit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//textFiel.setText(textField.getText());
//following command converts textfild value to integer
int centi = Integer.parseInt(textField.getText());
//----------------------------------------------------
//double area = 3.14*radius*radius;
int cb = list1.getSelectedIndex();//to get the index of selected item(eg. 0,1,2..)
if (cb == 0) {
Double inch = centi / 2.54;
//following command converts double to string
String out = Double.toString(inch);
//-----------------------------------------
textFiel.setText(out);
} else if (cb == 1) {
Double meter = centi / 100.00;
String out = Double.toString(meter);
textFiel.setText(out);
} else if (cb == 2) {
Double feet = centi / 30.48;
String out = Double.toString(feet);
textFiel.setText(out);
} else {
Double feet = centi / 12.00;
String out = Double.toString(feet);
textFiel.setText(out);
}
}
});
//c.setBackground(b);
Cr cr = new Cr();
cr.add(button);
cr.add(textField);
cr.add(list1);
cr.add(submit);
cr.add(textFiel);
button.setPreferredSize(new Dimension(150, 30));
frame.add(cr);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setVisible(true);
JOptionPane.showMessageDialog(frame, "Welcome \n enter centimeter in blank box\n Select your choice\n then press submit");
}
class Cr extends JPanel {
private static final long serialVersionUID = 1L;
private ImageIcon image = new ImageIcon("C:/Users/Public/Pictures/Sample Pictures/Desert.jpg");
#Override
public void paint(Graphics g) {
Dimension d = getSize();
for (int x = 0; x < d.width; x += image.getIconWidth()) {
for (int y = 0; y < d.height; y += image.getIconHeight()) {
g.drawImage(image.getImage(), x, y, null, null);
}
}
super.paint(g);
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
Test test = new Test();
}
});
}
}
I'll explain you your error:
Your test() method is a static method. It cannot access non-static methods/variables directly (this makes perfect programming sense, comment if you want me to elaborate). Static methods and variables can only access static members. You need to create an object of a static member and that object can access other non-static members.
As for the corrections required in your code, mKorbel's solution is perfect. However, to add an image to a JPanel, its best to "add" it as a JLabel, rather than to draw it. :
BufferedImage myPicture = ImageIO.read(new File("path-to-file"));
JLabel picLabel = new JLabel(new ImageIcon( myPicture ));
frame.add( picLabel );//see javadocs for JLabel for more info
EDIT
But you need a background image. The following is the corrected code:
class Cr extends JPanel{
//change here ('\\' is the escape sequence for '\') :
ImageIcon image = new ImageIcon("C:\\Users\\Public\\Pictures\\Sample Pictures\\Desert.jpg");
public void paint( Graphics g ) {
Dimension d = getSize();
for( int x = 0; x < d.width; x += image.getIconWidth() )
for( int y = 0; y < d.height; y += image.getIconHeight() )
g.drawImage( image.getImage(), x, y, null, null );
super.paint(g);
}
}

Categories