Results 1 to 8 of 8
- 08-24-2011, 06:18 PM #1
Member
- Join Date
- Jul 2011
- Posts
- 53
- Rep Power
- 0
Runnable JButton takes too much memory <-- Alternative?
So I got this custom made JButton that shows an animation when you put the mouse on it (in this case a sine wave propels). Now with 8 buttons of this type (the amount I'd like to use) in one JPanel this tends to give me a very slow JApplet. Thus what are alternatives I can use to get this animation? Without using a thread.
Java Code:import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Image; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.lang.Math; import javax.swing.JButton; public class CustomButton extends JButton implements MouseListener,Runnable { Color color1=new Color(0, 50, 0); Color color2=new Color(0, 150, 0); String text; int start=0; int adv,hgt; boolean mouseInside; Font font1 = new Font("Verdana",Font.BOLD, 12); FontMetrics fm=this.getFontMetrics(font1); Thread runner; public CustomButton(String text) { super(); this.text=text; setContentAreaFilled(false); setBorderPainted(false); addMouseListener(this); mouseInside=false; adv=fm.stringWidth(text); hgt=fm.getHeight(); runner = new Thread(this); runner.start(); } public void paintComponent(Graphics g) { g.setColor(color1); g.setFont(font1); g.fillRect(0, 0, 5, getHeight()); g.fillRect(getWidth()-5, 0, getWidth(), getHeight()); g.drawLine(0, getHeight()/2, getWidth(), getHeight()/2); DrawSine(g); g.setColor(color2); g.drawString(text, getWidth()/2-adv/2, getHeight()/2+hgt/4); } public void DrawSine(Graphics g) { int i=5; int j=start; while(i<getWidth()-5) { g.drawLine(i, (int)(Math.sin(6*Math.PI*(j-5)/(getWidth()-10))*((getHeight()/2)-5)+getHeight()/2), i+5, (int)(Math.sin(6*Math.PI*(j)/(getWidth()-10))*((getHeight()/2)-5)+getHeight()/2)); i=i+5; j=j+5; } } @Override public void mouseClicked(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) {[COLOR="red"]//When the mouse is in the Jbutton the boolean changes to true[/COLOR] // TODO Auto-generated method stub color1=new Color(0, 100, 0); color2=new Color(0, 200, 0); mouseInside=true; } @Override public void mouseExited(MouseEvent arg0) { [COLOR="red"]//When the mouse is out the Jbutton the boolean changes to false[/COLOR] // TODO Auto-generated method stub color1=new Color(0, 50, 0); color2=new Color(0, 150, 0); mouseInside=false; } @Override public void mousePressed(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void run() { [COLOR="red"]//The runner in question, checks if the mouseInside boolean is true and then start++ and repaint[/COLOR] // TODO Auto-generated method stub while(true) { synchronized (this) { if(mouseInside){ if (start<8*Math.PI) { start++; } else{start=0;} repaint(); try { wait (20); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } }
Last edited by Reskaillev; 08-24-2011 at 06:23 PM.
- 08-24-2011, 06:48 PM #2
- Join Date
- Sep 2008
- Location
- Voorschoten, the Netherlands
- Posts
- 14,421
- Blog Entries
- 7
- Rep Power
- 26
Don't call wait( ... ), it probably doesn't do what you have in mind. Call Thread.sleep( ... ) instead, and use a bit larger number.
kind regards,
JosBuild a wall around Donald Trump; I'll pay for it.
-
I would do things differently and use a pair of BufferedImages (one for the non-moving initial image and one that is 2X the width of the button for the moving image) and a Swing Timer that moves the image with an AffineTransform for this type of problem.
-
Heck, no need even for an AffineTransform. Just increment or decrement a variable.
Java Code:import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; import javax.swing.*; public class CustomButton2 extends JButton { private static final float STROKE_WIDTH = 3; private static final Color STILL_COLOR = Color.black; private static final Color MOVING_COLOR = Color.green; private static final int MOTION_PERIOD = 15; private static final int DELTA_X = 1; private BufferedImage stillImage; private BufferedImage movingImage; private boolean still = true; private int sineX = 0; private Timer motionTimer = new Timer(MOTION_PERIOD, new MotionListener()); public CustomButton2(String text) { super(text); addComponentListener(new MyCompListener()); addMouseListener(new MyMouseAdapter()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (still && stillImage != null) { g.drawImage(stillImage, 0, 0, null); } else if (!still && movingImage != null) { g.drawImage(movingImage, sineX, 0, null); } } private class MyMouseAdapter extends MouseAdapter { @Override public void mouseEntered(MouseEvent e) { still = false; repaint(); motionTimer.start(); } @Override public void mouseExited(MouseEvent e) { still = true; repaint(); motionTimer.stop(); } } private class MotionListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { sineX -= DELTA_X; sineX %= getWidth(); repaint(); } } private class MyCompListener extends ComponentAdapter { private void createImage() { Dimension d = getSize(); stillImage = createSineWaveImage(d, STILL_COLOR); movingImage = createSineWaveImage(d, MOVING_COLOR); } private BufferedImage createSineWaveImage(Dimension d, Color color) { BufferedImage myImage; myImage = new BufferedImage(d.width * 2, d.height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = myImage.createGraphics(); g2.setColor(color); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setStroke(new BasicStroke(STROKE_WIDTH)); drawSine(g2); g2.dispose(); return myImage; } private void drawSine(Graphics2D g2) { int delta = 2; int i = delta; int j = 0; while (i < 2* (getWidth() - delta)) { g2.drawLine(i, (int) (Math.sin(6 * Math.PI * (j - delta) / (getWidth() - 10)) * ((getHeight() / 2) - delta) + getHeight() / 2), i + delta, (int) (Math.sin(6 * Math.PI * (j) / (getWidth() - 10)) * ((getHeight() / 2) - delta) + getHeight() / 2)); i = i + delta; j = j + delta; } } @Override public void componentResized(ComponentEvent arg0) { createImage(); repaint(); } @Override public void componentShown(ComponentEvent arg0) { createImage(); repaint(); } } private static void createAndShowGui() { JPanel panel = new JPanel(new GridLayout(3, 3)); for (int i = 0; i < 9; i++) { panel.add(new CustomButton2("fubar")); } panel.setPreferredSize(new Dimension(400, 200)); JFrame frame = new JFrame("CustomButton"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(panel); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } }
Last edited by Fubarable; 08-24-2011 at 07:24 PM.
- 08-24-2011, 07:26 PM #5
- 08-24-2011, 07:30 PM #6
Member
- Join Date
- Jul 2011
- Posts
- 53
- Rep Power
- 0
mmh thnx for feedback XD
@Josh: I changed it to Thread.sleep(40), but the applet is still slow as hell :(
@Fubarable: Never worked with that but I'll see what I can do, I doesn't remove the thread problem though
@DarrylBurke: That might actually work :O, no idea what setRollovericon is but reading the API now
But is making the Jbutton runnable a correct and efficient solution for this problem?
Maybe something else exists?
Like a mouselistener that repeats checking if the mouse is inside?Last edited by Reskaillev; 08-24-2011 at 07:36 PM.
- 08-24-2011, 07:57 PM #7
Looks like this site doesn't allow hotlinking to images so I've uploaded them elsewhere.
The animation is a bit hasty because of a known Java incompatibility with certain animated GIFs and I don't feel like editing the GIF right now. Anyway it's sufficient to demonstrate what I'm suggesting. There's also a delay which won't be noticeable for images on the local hard disk or in the jar.
Java Code:import java.net.*; import javax.swing.*; public class RolloverAnimateButton { public static void main(String[] args) throws Exception { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new RolloverAnimateButton().makeUI(); } }); } public void makeUI() { String prefix = "http://i660.photobucket.com/albums/uu323/darrylbu/"; JButton button = new JButton(); try { button.setIcon(new ImageIcon(new URI(prefix + "Pwr0.gif").toURL())); button.setRolloverIcon(new ImageIcon(new URI(prefix + "Pwr.gif").toURL())); JFrame frame = new JFrame(); frame.add(button); frame.pack(); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } catch (URISyntaxException ex) { ex.printStackTrace(); } catch (MalformedURLException ex) { ex.printStackTrace(); } } }
- 08-24-2011, 08:12 PM #8
Member
- Join Date
- Jul 2011
- Posts
- 53
- Rep Power
- 0
Similar Threads
-
Do I have what it takes.
By phil128 in forum Jobs DiscussionReplies: 0Last Post: 03-04-2011, 12:32 PM -
Need help with a program that takes letters and then dumps them back out
By Adde1986 in forum New To JavaReplies: 2Last Post: 04-09-2009, 10:46 PM -
Which InputStream takes the least memory?
By arnab321 in forum New To JavaReplies: 9Last Post: 01-13-2009, 05:45 PM -
how do I increase memory allocated to code cache (Non Heap Memory)
By manibhat in forum Advanced JavaReplies: 2Last Post: 08-21-2008, 07:33 PM -
It takes very long time.....
By iresha in forum Advanced JavaReplies: 6Last Post: 05-11-2008, 02:31 AM
Bookmarks