Movement stuck when clicking buttons - java

Created a Program similar to paint where there is a rectangle whose movement inside the screen can be controlled by "w,a,s,d" keys and its size increased or decreased using the scroller on the mouse. There are also several buttons of various colours which when pressed fills the rectangular shape with the respective colours. Now the problem is after clicking any colour button the movement is stopped ie. the rectangle doesn't move. You can increase and decrease its size but you can't move with "w,a,s,d" keys. Please do help me with that.
And also as an optional request, I'm also trying to paint with this rectangle ie. when I press the space bar I want to fill the colour which is selected at the specified area. Now even though I can do that. The next action I do ie. either pressing "w,a,s,d" keys or the scroller, the colour disappears. Now I know that the colour or fillRect() has to be saved somehow so that the next action doesn't affect it, but I've tried several ways but it isn't happening. I've commented the code for the painting below.
My first request is my main request, the second one if you are unable to understand what I mean or don't know the solution just leave it.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Animation extends Frame implements KeyListener,MouseWheelListener,ActionListener {
int x,y,a,b;
char choice1;
int draw=1;
int n=0;
int color1,color2,color3;
Button button1,button2,button3,button4,button5,button6,button7,button8,button9,button10;
Animation() {
setSize(1000, 1000);
setVisible(true);
x = 500;
y = 500;
a = 20;
b = 50;
addKeyListener(this);
addMouseWheelListener(this);
JFrame frame = new JFrame();
frame.getContentPane().setLayout(null);
button1 = new Button("Black");
button2 = new Button("Blue");
button3 = new Button("Green");
button4 = new Button("Orange");
button5 = new Button("Red");
button6 = new Button("Yellow");
button7 = new Button("Gray");
button8 = new Button("Cyan");
button9 = new Button("Magenta");
button10 = new Button("Pink");
add(button1);add(button2);add(button3);add(button4);add(button5);
add(button6);add(button7);add(button8);add(button9);add(button10);
button1.setBounds(50,680,50,20); button2.setBounds(120,680,50,20);
button3.setBounds(190,680,50,20); button4.setBounds(260,680,50,20);
button5.setBounds(330,680,50,20); button6.setBounds(400,680,50,20);
button7.setBounds(470,680,50,20); button8.setBounds(540,680,50,20);
button9.setBounds(610,680,50,20); button10.setBounds(680,680,50,20);
button1.addActionListener(this);button2.addActionListener(this);
button3.addActionListener(this);button4.addActionListener(this);
button5.addActionListener(this);button6.addActionListener(this);
button7.addActionListener(this);button8.addActionListener(this);
button9.addActionListener(this);button10.addActionListener(this);
addWindowListener(new WindowListener() {
#Override
public void windowOpened(WindowEvent e) {
}
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
#Override
public void windowClosed(WindowEvent e) {
}
#Override
public void windowIconified(WindowEvent e) {
}
#Override
public void windowDeiconified(WindowEvent e) {
}
#Override
public void windowActivated(WindowEvent e) {
}
#Override
public void windowDeactivated(WindowEvent e) {
}
});
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
choice1 = e.getKeyChar();
if (choice1 == 'w') {
y = y - 10;
}
if (choice1 == 's') {
y = y + 10;
}
if (choice1 == 'a') {
x = x - 10;
}
if (choice1 == 'd') {
x = x + 10;
}
if(choice1 == ' '){
draw=2;
}
repaint();
}
#Override
public void mouseWheelMoved(MouseWheelEvent e) {
double p = e.getPreciseWheelRotation();
if(p>0){
a=a+5;
b=b+5;
} else{
a=a-5;
b=b-5;
}
repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("Black")){
color1 = 0;
color2 = 0;
color3 = 0;
}
if(e.getActionCommand().equals("Blue")){
color1 = 0;
color2 = 0;
color3 = 255;
}
if(e.getActionCommand().equals("Green")){
color1 = 0;
color2 = 255;
color3 = 0;
}
if(e.getActionCommand().equals("Orange")){
color1 = 255;
color2 = 165;
color3 = 0;
}
if(e.getActionCommand().equals("Red")){
color1 = 255;
color2 = 0;
color3 = 0;
}
if(e.getActionCommand().equals("Yellow")){
color1 = 255;
color2 = 255;
color3 = 0;
}
if(e.getActionCommand().equals("Gray")){
color1 = 169;
color2 = 169;
color3 = 169;
}
if(e.getActionCommand().equals("Cyan")){
color1 = 0;
color2 = 255;
color3 = 255;
}
if(e.getActionCommand().equals("Magenta")){
color1 = 255;
color2 = 0;
color3 = 255;
}
if(e.getActionCommand().equals("Pink")){
color1 = 255;
color2 = 192;
color3 = 203;
}
repaint();
}
public void paint(Graphics g) {
if(draw==1) {
g.drawRect(x, y, a, b);
g.setColor(new Color(color1,color2,color3));
g.fillRect(x,y,a,b);
}
// if(draw==2){
// fillColor(g);
// draw=1;
// }
}
// public void fillColor(Graphics g){
// g.setColor(Color.red);
// int[] temp1 = new int[50];
// temp1[n] = x;
// int[] temp2 = new int[50];
// temp2[n] = y;
// int[] temp3 = new int[50];
// temp3[n] = a;
// int[] temp4 = new int[50];
// temp4[n] = b;
//
//
// n++;
// for (int i=0;i<n;i++){
// System.out.println("abcd");
// g.fillRect(temp1[n],temp2[n],temp3[n],temp4[n]);
// }
//
// }
public static void main(String[] args) {
Animation animation = new Animation();
}
}

First of all there are basic design issues:
Don't extend Frame. There is no need to extend any class.
Don't use AWT components in a Swing application. JFrame is Swing. "Button" is AWT. For Swing your should be using JButton.
Don't use a null layout for the entire frame. Keep the default BorderLayout. Read the section from the Swing tutorial on How to Use BorderLayout.
For the buttons you should create a JPanel (which by default uses a FlowLayout) and add your buttons to this panel.
Then you add this panel to your frame using:
frame.add(buttonPanel, BorderLayout.PAGE_END);
Custom painting is done by extending JPanel and then you override the paintComponent(...) method. So you need to create a DrawingPanel to paint your rectangle. Read the Swing tutorial on Custom Painting for working examples to help you structure your code better.
Then you add the drawing panel to the frame using:
frame.add(drawingPanel, BorderLayout.CENTER):
Don't use a WindowListener to close the frame.
When you create the frame you can set the close property:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Using multiple nested if statements, like you do in the ActionListner is poor design. As you continue to support more colors the code just grows and grows. An alternative approach might be:
a) create a HashMap as an instance variable to contain the buttons and colors:
private HashMap<JButton, Color> buttonColors = new HashMap<>();
private Color rectangleColor = Color.BLACK;
b) now when you create each button you can update the hash map:
buttonColors.put(button1, Color.BLACK);
c) now the code in your ActionListener becomes:
JButton button = (JButton)e.getSource();
Color color = buttonColors.get(button);
rectangleColor = color;
repaint();
d) and the code in your paintComponent() method becomes:
//g.setColor(new Color(color1,color2,color3));
g.setColor( rectangleColor );
Don't create your buttons by brute force. Create a method.
Code to invoke method
buttonsPanel.add( createButton("Black", Color.BLACK) );
buttonsPanel.add( createButton("Blue", Color.BLUE) );
and the createButton(..) method would look something like:
public JButton (String text, Color color)
{
JButton button = new JButton( text );
button.addActionListener(this);
buttonColors.put(button, color);
return button;
}
A lot of suggestions here. The code is posted without testing, so understand each concept and make a change one at a time and test to make sure you implement each step correctly.
Now the problem is after clicking any colour button the movement is stopped ie. the rectangle doesn't move.
A KeyEvent is only passed to the component with focus. When you click on a button the painting panel loses focus and no longer responds to events.
The better solution is to use Key Bindings. Key bindings will work even when a component doesn't have focus. See: Motion Using the Keyboard for more information and working examples.

Short answer for the first. Add:
button1.setFocusable(false);
button2.setFocusable(false);
button3.setFocusable(false);
button4.setFocusable(false);
button5.setFocusable(false);
button6.setFocusable(false);
button7.setFocusable(false);
button8.setFocusable(false);
button9.setFocusable(false);
button10.setFocusable(false);

Related

Java Choice Menu Difficulties, Colour and Draw_Line

I'm trying to create a MS Paint-like software with Java Choice Menus, but I'm experiencing some difficulties with two functions in particular
I get a massive wall of error text upon selecting a colour from my Colour Menu. What I wish to achieve is selecting the colour converts the string containing the option into lower case, before setting the PenColour into that option
Drawing Lines don't seem to work, despite the same code being functional in a different applet that didn't use Choice. I want it to select two points which then have a line drawn between them.
Here is my Code
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.awt.Choice;
public class PockettProjectTest1 extends Applet implements ActionListener, MouseListener, MouseMotionListener{
//Coordinates and sizes used to draw GUI
private final int GUI_HEIGHT = 100;
private final int GUI_START_X = 10;
private final int GUI_START_Y = 10;
private final int FIELD_SIZE = 11; //Numbers of characters for text field display
////////////////////////GLOBAL VARIABLES////////////////////////
private Dimension appletSize; //used to encapsulate the Applets dimensions
private int x, y, appletHeight, appletWidth, PenThick, PenMode, ShapeMode, ClickXO, ClickYO, ClickXN, ClickYN, ClickCount;
private String SizeString;
//a Panel is a container used here to hold and position the GUI components
private Panel guiPanel;
private Color PenColour;
//GUI components cv
public void init(){
//Disables the applet layout manager and stops automatic GUI component positioning
setLayout(null);
setBackground(Color.white);
addMouseListener(this);
addMouseMotionListener(this);
addMouseListener(this);
ClickCount = 0;
ClickXO = 0;
ClickYO = 0;
ClickXN = 0;
ClickYN = 0;
PenMode = 0;
ShapeMode = 0;
appletSize = this.getSize(); //captures the Applet dimensions
appletHeight = appletSize.height; //captures the Applet height
appletWidth = appletSize.width; //captures the Applet width
//Set up the Panel ready to hold the GUI components
guiPanel = new Panel();
guiPanel.setLocation(0, 0);
guiPanel.setSize(appletWidth,GUI_HEIGHT);
guiPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 40));
guiPanel.setBackground(Color.lightGray);
add(guiPanel);
Choice mode = new Choice();
Choice size = new Choice();
Choice color = new Choice();
Choice shape = new Choice();
mode.add("Pen");
mode.add("Eraser");
mode.add("Fill");
mode.add("Shape");
size.add("01px");
size.add("02px");
size.add("03px");
size.add("05px");
size.add("10px");
size.add("15px");
size.add("20px");
size.add("30px");
size.add("50px");
shape.add("N/A");
shape.add("Line");
shape.add("Oval");
shape.add("Oblong");
shape.add("Square");
shape.add("Circle");
shape.add("FillOval");
shape.add("FillOblong");
shape.add("FillSquare");
shape.add("FillCircle");
//add choice or combobox
guiPanel.add(mode);
guiPanel.add(size);
guiPanel.add(shape);
PenThick = 1;
PenColour = Color.black;
mode.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent ie)
{
PenMode = mode.getSelectedIndex();
}
});
size.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent ie)
{
SizeString = size.getSelectedItem();
PenThick = Integer.parseInt(SizeString.substring(0,2));
Graphics g = getGraphics();
}
});
//// Start of Issue 1:
colour.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent ie)
{
ColourString = colour.getSelectedItem();
ColourString.toLowerCase();
Color PenColour.getColor(ColourString);
}
});
/// End of Issue 1
shape.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent ie)
{
ShapeMode = shape.getSelectedIndex();
}
});
}
public void actionPerformed(ActionEvent e) {
}
////Issue 2:
public void mouseReleased(MouseEvent me){
if (PenMode == 3) {
if (ClickCount == 0) {
ClickXO = me.getX();
ClickYO = me.getY();
ClickCount ++;
System.out.println(ClickCount);
return;
}
if (ClickCount == 1) {
ClickXN = me.getX();
ClickYN = me.getY();
System.out.println(ClickCount);
Graphics g = getGraphics();
g.setColor(Color.black);
g.drawLine(ClickXO, ClickYO, ClickXN, ClickYN);
System.out.println(ClickXO);
System.out.println(ClickYO);
System.out.println(ClickXN);
System.out.println(ClickYN);
ClickCount = 0;
}
}
}
/// End of Issue 2
public void mousePressed(MouseEvent e){
}
public void mouseDragged(MouseEvent e){
if (PenMode == 0){
Graphics g = getGraphics();
g.setColor(Color.black);
g.fillOval(e.getX(), e.getY(), PenThick, PenThick);
}
if (PenMode == 1){
Graphics g = getGraphics();
g.setColor(Color.white);
g.fillRect(e.getX(), e.getY(), PenThick, PenThick);
}
}
public void mouseMoved(MouseEvent e){
}
public void mouseExited(MouseEvent e){
}
public void mouseEntered(MouseEvent e){
}
public void mouseClicked(MouseEvent e){
}
}
I have to have this code due by the end of Friday, so I hope I can get the issue solved by then.

Make running (marquee ) of JLabel in Netbeans [duplicate]

How can I implement Marquee effect in Java Swing
Here's an example using javax.swing.Timer.
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
/** #see http://stackoverflow.com/questions/3617326 */
public class MarqueeTest {
private void display() {
JFrame f = new JFrame("MarqueeTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String s = "Tomorrow, and tomorrow, and tomorrow, "
+ "creeps in this petty pace from day to day, "
+ "to the last syllable of recorded time; ... "
+ "It is a tale told by an idiot, full of "
+ "sound and fury signifying nothing.";
MarqueePanel mp = new MarqueePanel(s, 32);
f.add(mp);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
mp.start();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new MarqueeTest().display();
}
});
}
}
/** Side-scroll n characters of s. */
class MarqueePanel extends JPanel implements ActionListener {
private static final int RATE = 12;
private final Timer timer = new Timer(1000 / RATE, this);
private final JLabel label = new JLabel();
private final String s;
private final int n;
private int index;
public MarqueePanel(String s, int n) {
if (s == null || n < 1) {
throw new IllegalArgumentException("Null string or n < 1");
}
StringBuilder sb = new StringBuilder(n);
for (int i = 0; i < n; i++) {
sb.append(' ');
}
this.s = sb + s + sb;
this.n = n;
label.setFont(new Font("Serif", Font.ITALIC, 36));
label.setText(sb.toString());
this.add(label);
}
public void start() {
timer.start();
}
public void stop() {
timer.stop();
}
#Override
public void actionPerformed(ActionEvent e) {
index++;
if (index > s.length() - n) {
index = 0;
}
label.setText(s.substring(index, index + n));
}
}
I know this is a late answer, but I just saw another question about a marquee that was closed because it was considered a duplicate of this answer.
So I thought I'd add my suggestion which takes a approach different from the other answers suggested here.
The MarqueePanel scrolls components on a panel not just text. So this allows you to take full advantage of any Swing component. A simple marquee can be used by adding a JLabel with text. A fancier marquee might use a JLabel with HTML so you can use different fonts and color for the text. You can even add a second component with an image.
Basic answer is you draw your text / graphic into a bitmap and then implement a component that paints the bitmap offset by some amount. Usually marquees / tickers scroll left so the offset increases which means the bitmap is painted at -offset. Your component runs a timer that fires periodically, incrementing the offset and invalidating itself so it repaints.
Things like wrapping are a little more complex to deal with but fairly straightforward. If the offset exceeds the bitmap width you reset it back to 0. If the offset + component width > bitmap width you paint the remainder of the component starting from the beginning of the bitmap.
The key to a decent ticker is to make the scrolling as smooth and as flicker free as possible. Therefore it may be necessary to consider double buffering the result, first painting the scrolling bit into a bitmap and then rendering that in one go rather than painting straight into the screen.
Here is some code that I threw together to get you started. I normally would take the ActionListener code and put that in some sort of MarqueeController class to keep this logic separate from the panel, but that's a different question about organizing the MVC architecture, and in a simple enough class like this it may not be so important.
There are also various animation libraries that would help you do this, but I don't normally like to include libraries into projects only to solve one problem like this.
public class MarqueePanel extends JPanel {
private JLabel textLabel;
private int panelLocation;
private ActionListener taskPerformer;
private boolean isRunning = false;
public static final int FRAMES_PER_SECOND = 24;
public static final int MOVEMENT_PER_FRAME = 5;
/**
* Class constructor creates a marquee panel.
*/
public MarqueePanel() {
this.setLayout(null);
this.textLabel = new JLabel("Scrolling Text Here");
this.panelLocation = 0;
this.taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
MarqueePanel.this.tickAnimation();
}
}
}
/**
* Starts the animation.
*/
public void start() {
this.isRunning = true;
this.tickAnimation();
}
/**
* Stops the animation.
*/
public void stop() {
this.isRunning = false;
}
/**
* Moves the label one frame to the left. If it's out of display range, move it back
* to the right, out of display range.
*/
private void tickAnimation() {
this.panelLocation -= MarqueePanel.MOVEMENT_PER_FRAME;
if (this.panelLocation < this.textLabel.getWidth())
this.panelLocaton = this.getWidth();
this.textLabel.setLocation(this.panelLocation, 0);
this.repaint();
if (this.isRunning) {
Timer t = new Timer(1000 / MarqueePanel.FRAMES_PER_SECOND, this.taskPerformer);
t.setRepeats(false);
t.start();
}
}
}
Add a JLabel to your frame or panel.
ScrollText s= new ScrollText("ello Everyone.");
jLabel3.add(s);
public class ScrollText extends JComponent {
private BufferedImage image;
private Dimension imageSize;
private volatile int currOffset;
private Thread internalThread;
private volatile boolean noStopRequested;
public ScrollText(String text) {
currOffset = 0;
buildImage(text);
setMinimumSize(imageSize);
setPreferredSize(imageSize);
setMaximumSize(imageSize);
setSize(imageSize);
noStopRequested = true;
Runnable r = new Runnable() {
public void run() {
try {
runWork();
} catch (Exception x) {
x.printStackTrace();
}
}
};
internalThread = new Thread(r, "ScrollText");
internalThread.start();
}
private void buildImage(String text) {
RenderingHints renderHints = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
renderHints.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
BufferedImage scratchImage = new BufferedImage(1, 1,
BufferedImage.TYPE_INT_RGB);
Graphics2D scratchG2 = scratchImage.createGraphics();
scratchG2.setRenderingHints(renderHints);
Font font = new Font("Serif", Font.BOLD | Font.ITALIC, 24);
FontRenderContext frc = scratchG2.getFontRenderContext();
TextLayout tl = new TextLayout(text, font, frc);
Rectangle2D textBounds = tl.getBounds();
int textWidth = (int) Math.ceil(textBounds.getWidth());
int textHeight = (int) Math.ceil(textBounds.getHeight());
int horizontalPad = 600;
int verticalPad = 10;
imageSize = new Dimension(textWidth + horizontalPad, textHeight
+ verticalPad);
image = new BufferedImage(imageSize.width, imageSize.height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = image.createGraphics();
g2.setRenderingHints(renderHints);
int baselineOffset = (verticalPad / 2) - ((int) textBounds.getY());
g2.setColor(Color.BLACK);
g2.fillRect(0, 0, imageSize.width, imageSize.height);
g2.setColor(Color.GREEN);
tl.draw(g2, 0, baselineOffset);
// Free-up resources right away, but keep "image" for
// animation.
scratchG2.dispose();
scratchImage.flush();
g2.dispose();
}
public void paint(Graphics g) {
// Make sure to clip the edges, regardless of curr size
g.setClip(0, 0, imageSize.width, imageSize.height);
int localOffset = currOffset; // in case it changes
g.drawImage(image, -localOffset, 0, this);
g.drawImage(image, imageSize.width - localOffset, 0, this);
// draw outline
g.setColor(Color.black);
g.drawRect(0, 0, imageSize.width - 1, imageSize.height - 1);
}
private void runWork() {
while (noStopRequested) {
try {
Thread.sleep(10); // 10 frames per second
// adjust the scroll position
currOffset = (currOffset + 1) % imageSize.width;
// signal the event thread to call paint()
repaint();
} catch (InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}
public void stopRequest() {
noStopRequested = false;
internalThread.interrupt();
}
public boolean isAlive() {
return internalThread.isAlive();
}
}
This is supposed to be an improvement of #camickr MarqueePanel. Please see above.
To map mouse events to the specific components added to MarqueePanel
Override add(Component comp) of MarqueePanel in order to direct all mouse events of the components
An issue here is what do do with the MouseEvents fired from the individual components.
My approach is to remove the mouse listeners form the components added and let the MarqueePanel redirect the event to the correct component.
In my case these components are supposed to be links.
#Override
public Component add(Component comp) {
comp = super.add(comp);
if(comp instanceof MouseListener)
comp.removeMouseListener((MouseListener)comp);
comp.addMouseListener(this);
return comp;
}
Then map the component x to a MarqueePanel x and finally the correct component
#Override
public void mouseClicked(MouseEvent e)
{
Component source = (Component)e.getSource();
int x = source.getX() + e.getX();
int y = source.getY();
MarqueePanel2 marqueePanel = (MarqueePanel2) ((JComponent)e.getSource()).getParent();
double x2 = marqueePanel.getWidth();
double x1 = Math.abs(marqueePanel.scrollOffset);
if(x >= x1 && x <= x2)
{
System.out.println("Bang " + x1);
Component componentAt = getComponentAt(x+marqueePanel.scrollOffset, y);
if(comp instanceof MouseListener)
((MouseListener) componentAt).mouseClicked(e);
System.out.println(componentAt.getName());
}
else
{
return;
}
//System.out.println(x);
}

Repainting JPanel

So i'm trying to clear my drawing Panel and I have looked at multiple examples but none of them seem to be working for me? I have a clear button that clears textfields/errors which I got to work perfectly but the Drawing panel still does not clear arraylists or "repaint".
I'm playing around with changing around the size of the oval so please ignore my drawPoints method.
Here is my code:
public class Panel extends JPanel{
ArrayList<Point> pointArray = new ArrayList<>();
ArrayList<Color> colorArray = new ArrayList<>();
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
repaint();
//Create the 2D graphics object
Graphics2D myDrawing = (Graphics2D) g;
for (int i = 0; i < pointArray.size(); i++) {
myDrawing.setColor(colorArray.get(i));
myDrawing.fillOval(pointArray.get(i).x,pointArray.get(i).y, 10, 10);
}
}
public void drawPoints(int mouseX, int mouseY, int height, int width){
Point p = new Point(mouseX,mouseY);
pointArray.add(p);
colorArray.add(this.getForeground());
repaint();
}
public void changeColor(){
int red = (int) (Math.random() * 256);
int green = (int) (Math.random() * 256);
int blue = (int) (Math.random() * 256);
this.setForeground(new Color(red,green,blue));
}
public void mousePressed(MouseEvent event) {
pointArray.clear();
colorArray.clear();
repaint();
}
}
public static void main(String[] args) {
//set the frame
JFrame frame = new JFrame();
frame.setSize(600, 300);
frame.setTitle("Multiple Panels");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//create the panel for GUI
JPanel panelGUI = new JPanel();
panelGUI.setBackground(Color.yellow);
//GUIs
//create textfields
JTextField radiusField1 = new JTextField("10", 10);
JTextField radiusField2 = new JTextField("10", 10);
//create buttons
final JButton clearDrawingButton = new JButton("Clear Screen");
final JButton changeColorButton = new JButton("Change Color");
//labels
final JLabel displayLabel = new JLabel("");
//add all GUIs to the GUI panel
panelGUI.add(radiusField1);
panelGUI.add(radiusField2);
panelGUI.add(changeColorButton);
panelGUI.add(clearDrawingButton);
panelGUI.add(displayLabel);
//create the panel to draw
final Panel drawingPanel = new Panel();
drawingPanel.setBackground(Color.white);
//create the initial color
Color drawingColor = new Color(255,0,0);
//set the initial drawing color of the panel
drawingPanel.setForeground(drawingColor);
//add the grid with two columns and two rows to add the three panels
GridLayout grid = new GridLayout(0,2,10,20);
//add the grid to the frame
frame.setLayout(grid);
//add the panels to the frame
frame.add(panelGUI);
frame.add(drawingPanel);
class MouseClickListener implements MouseListener
{
public void mouseClicked(MouseEvent event)
{
int x = event.getX();
int y = event.getY();
System.out.println(x + " " + y);
try {
String text1 = radiusField1.getText();
String text2 = radiusField2.getText();
int height = Integer.parseInt(text1);
int width = Integer.parseInt(text2);
drawingPanel.drawPoints(x, y, height, width);
} catch (NumberFormatException ex) {
displayLabel.setText("Textfields empty! Please enter number.");}
}
// Do­nothing methods
public void mouseReleased(MouseEvent event) {}
public void mousePressed(MouseEvent event) {}
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
}
class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if (event.getSource()== changeColorButton){
drawingPanel.changeColor();
}
if(event.getSource()==clearDrawingButton){
radiusField1.setText("10");
radiusField2.setText("10");
displayLabel.setText("");
}
}
}
MouseListener listener1 = new MouseClickListener();
drawingPanel.addMouseListener(listener1);
ActionListener listener = new ButtonListener();
changeColorButton.addActionListener(listener);
clearDrawingButton.addActionListener(listener);
frame.setVisible(true);
}
}
I have a clear button that clears textfields/errors which I got to work perfectly but the Drawing panel still does not clear arraylists or "repaint".
Well look at the code that clears the text fields:
if(event.getSource()==clearDrawingButton){
radiusField1.setText("10");
radiusField2.setText("10");
displayLabel.setText("");
}
Where is the code that clears the ArrayLists?
Add the code to clear the ArrayLists to the ActionListener.
You can also check out Custom Painting Approaches for working code that draws "rectangles". It supports different colors and a "Clear" button.
Also, instead of using a JTextField for the oval size, you might want to consider using a JSpinner. This will allow the user to easily change the numeric value and you don't have to add any special editing to make sure the value entered is a number.
You have this mousePressed method in your main class:
public void mousePressed(MouseEvent event) {
pointArray.clear();
colorArray.clear();
repaint();
}
But it isn't doing anything because your main class does not implement MouseListener and no one is calling this method.
The rest of your code is not very pretty looking. I assume you are doing this as part of a course or otherwise just trying to learn Java Swing in a non-work environment. If this is true, I would recommend that you start over - at least with your MouseListeners, and instead create Actions for your button responses by subclassing AbstractAction and using it with JButton.setAction(myAction); This may seem painful now, but you'll be glad you did it in the future

Cannot display image icon

I have to display images using the fly weight pattern, I can't get the images to print to screen, here's the code that demonstrates the problem.
public void draw(Graphics g, int tx, int ty, String name) {
grem.paintIcon(null, g, tx, ty);
g.drawString(name, tx, ty + H + 15 );
ImageIcon grem = new ImageIcon("../images/grem.png");
}
/// next class that calls the above class
public void paint(Graphics g) {
Folder folderIcon;
String name;
int j = 0; //count number in row
int row = Top; //start in upper left
int x = Left;
//go through all the names and folders
for (int i = 0; i< names.size(); i++) {
name = (String)names.elementAt(i);
if (name.equals(selectedName))
folderIcon = fact.getFolder(true);
else
folderIcon = fact.getFolder(false);
//have that folder draw itself at this spot
folderIcon.paint(g);
x = x + HSpace; //change to next posn
j++;
if (j >= HCount) { //reset for next row
j = 0;
row += VSpace;
x = Left;
}
}
}
Don't override paint(). Custom painting is done by overriding paintComponent().
Don't do I/O in a painting method. You can't control when Swing will repaint a component so you don't want to read images in the painting method. The images should be read in the constructor of your class.
Override the getPreferredSize(...) method to return the size of your component, otherwise the size of the component will be (0, 0) so there may be nothing to paint (depending on the layout manager being used.
If you need more help the post a proper SSCCE that demonstrates the problem because we don't know the context of how your code is being used and don't have time to spend guessing what you may or may not be doing.
Read the section from the Swing tutorial on Custom Painting for more information. Also, instead of doing custom painting you could also use a JList to display the Icon in a grid pattern. Check out the table of contents for the tutorial link to find the section on How to Use Lists for more information.
Maybe the null is the problem : it should be something like this if im not mistaken
class MyComponent extends JComponent {
public void paint(Graphics g) {
ImageIcon icon = new ImageIcon("a.png");
int x = 0;
int y = 100;
icon.paintIcon(this, g, x, y);
}
public class Gremlin extends JFrame implements ActionListener {
String names[] = {"Andy","Bill","Bob","Dan","Eugene","Frank","Gary","Harry","Ian","Jack",
"Killlian","Liam","Mark","Nial","Obi","Phil","Richard","Stephan","Terry","Viny",}; // 20 names
public Icon img = new ImageIcon("grem1.jpg");
public JLabel grem = new JLabel(img);
JLabel bigLabel = new JLabel();
JLabel grem2 = new JLabel("New Gremlin");
public JPanel panel2 = new JPanel();
JPanel panel = new JPanel();
public Gremlin() {
JButton button = new JButton("Add Gremlin");
this.add(panel);
panel.setLayout(new GridLayout(9,6));
panel.add(panel2);
panel2.add(button);
for(int i = 0; i<20; i++){
bigLabel.add(grem = new JLabel(names[i]), panel.add(grem = new JLabel(img)));
panel.add(bigLabel);
}
button.addActionListener(this);
setSize(550,600);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
Gremlin frame = new Gremlin();
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource() != null ){
System.out.println("add a Gremlin");
panel.add(grem = new JLabel("NEW GREMLIN"), panel.add(grem = new JLabel(img)));
revalidate();
}
}
}

image not overlapping button

i want to overlap image on button(when it is clicked)....but on clicking it is not overlapping....please guide me where i am wrong....is it not possible to do so???
i am using frame to add buttons....
import java.awt.*;
import java.awt.event.*;
public class d extends Frame implements ActionListener {
Image img, i1, i2;
int x, y;
String msg;
Button one, two;
d() {
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setSize(1000, 500);
setVisible(true);
setLayout(null);
one = new Button("1");
two = new Button("2");
add(one);
add(two);
one.addActionListener(this);
two.addActionListener(this);
one.setBounds(200, 100, 100, 100);
two.setBounds(300, 100, 100, 100);
}
public void actionPerformed(ActionEvent e) {
msg = e.getActionCommand();
if (msg.equals("1")) {
msg = "Pressed 1";
img = i1;
x = 200;
y = 100;
} else {
msg = "Pressed 2";
img = i2;
x = 300;
y = 100;
}
repaint();
}
public void paint(Graphics g) {
Toolkit tool = Toolkit.getDefaultToolkit();
i1 = tool.getImage("F:/Memories/rawk garden/a.jpg");
i2 = tool.getImage("F:/Memories/rawk garden/b.jpg");
g.drawImage(img, x, y, 100, 100, this);
g.drawString(msg, 100, 300);
}
public static void main(String s[]) {
new d();
}
}
I have already shared you code for this in your last post where I suggested you some points with the sample code to achieve it using JLabel.
Read more points...
Don't use null layout. There are lots of Layout Managers choose any one that suits as per your application design.
How to Use Various Layout Managers
From comments below:
actually I am making minesweeper type game...i want button to change into image and once one button is converted to image...that image remains there.
Use JButton#setIcon() method to set the icon of the button.
Here is the sample code where
I have created a 9x9 grid that contains buttons.
Each cell has a random boolean flag whether it has mine or not.
When button is clicked I am setting its icon if it has mine.
Simply set the text empty and make it disabled to stop further clicks on already clicked button.
sample code:
final Image mine = ImageIO.read(new File("resources/mine.png"));
final boolean[][] showMine = new boolean[9][9];
Random random = new Random();
JPanel panel = new JPanel(new GridLayout(9, 9));
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
showMine[i][j] = random.nextBoolean();
final int x = i;
final int y = j;
final JButton button = new JButton();
button.setText(String.valueOf(i * 9 + j));
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
button.setEnabled(false);
button.setText("");
if (showMine[x][y]) {
button.setDisabledIcon(new ImageIcon(mine));
}
}
});
panel.add(button);
}
}
add(panel);
snapshot:
Setting an image on a button can be done as follows:
Button myButton = new Button(new ImageIcon("image_path"));

Categories

Resources