Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>There a number of problems with you entire program, the choice of <code>null</code> layouts is a significant one, this is going to cause you a lot of problems.</p> <p>But, the significant problem you're facing is in your <code>paint</code> method</p> <pre><code>public void paint(Graphics g) { super.paint(g); Random r = new Random(); String s = ""; s = str[r.nextInt(str.length)]; System.out.println(s); img = getToolkit().getImage(s); g.drawImage(img, this.x, this.y, 100, 150, this); } </code></pre> <p>There are three problems with this method.</p> <ol> <li>You should be overriding <code>paintComponent</code>, its a safer method for performing custom painting.</li> <li>You're regenerate the image random on each paint cycle. You have to remember that the your component may be painted for any number of reasons and most outside of your control. This means that every time the component is painted, a new image is loaded. You should be assigning a single image to the component when it is constructed and paint that image.</li> <li>The <code>Graphics</code> context passed to your component has been translated so that the point 0x0 will be at the top left corner of the component. This means, all painting is relative.</li> </ol> <p>Your code does this...</p> <pre><code>g.drawImage(img, this.x, this.y, 100, 150, this); </code></pre> <p>This means, that the image will be painted at x/y pixels relative to the top/left position of the component. Instead, you should be painting around the 0x0 position.</p> <p>In your example, you also do</p> <pre><code>jfrm.setVisible(true); jfrm.getContentPane().add(cc); </code></pre> <p>This is generally a bad idea, you should switch these two statements, otherwise it will look like nothing has been painted.</p> <p>You may find it worth while to take a read through</p> <ul> <li><a href="http://docs.oracle.com/javase/tutorial/uiswing/painting/" rel="nofollow noreferrer">Performing Custom Painting</a></li> <li><a href="http://www.oracle.com/technetwork/java/painting-140037.html" rel="nofollow noreferrer">Painting in AWT and Swing</a></li> <li><a href="http://docs.oracle.com/javase/tutorial/2d/" rel="nofollow noreferrer">2D Graphics</a></li> </ul> <p><strong>Update with a simple example</strong></p> <p>This example is intended to demonstrate the quantity of hits that a <code>paint</code> method can take as well as the concept of local coordinate space.</p> <p><img src="https://i.stack.imgur.com/ddlP2.png" alt="enter image description here"></p> <pre><code>import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.GridBagLayout; import java.awt.Image; import java.io.File; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class Cards { public static void main(String[] args) { new Cards(); } public Cards() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame jfrm = new JFrame(); jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jfrm.setSize(100, 150); jfrm.setVisible(true); jfrm.add(new TestPane()); } }); } public class TestPane extends JPanel { public TestPane() { CardComponent cc = new CardComponent(); setLayout(new GridBagLayout()); add(cc); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); FontMetrics fm = g.getFontMetrics(); // Simply render the location of the component relative to it's parent. for (Component comp : getComponents()) { String text = comp.getX() + "x" + comp.getY(); g.drawString(text, comp.getX(), comp.getY() - fm.getHeight() + fm.getAscent()); } } } public class CardComponent extends JPanel { String[] str; Image img; private int paintCount; public CardComponent() { File[] files = new File("C:\\Users\\swhitehead\\Documents\\My Dropbox\\MegaTokyo").listFiles(); str = new String[files.length]; for (int index = 0; index &lt; files.length; index++) { str[index] = files[index].getPath(); } setOpaque(false); setVisible(true); } @Override public Dimension getPreferredSize() { return new Dimension(100, 150); } @Override public Dimension getMinimumSize() { return getPreferredSize(); } public void paint(Graphics g) { paintCount++; System.out.println(paintCount); super.paint(g); Random r = new Random(); String s = ""; s = str[r.nextInt(str.length)]; img = getToolkit().getImage(s); // Drawing image in the top left corner of the component g.drawImage(img, 0, 0, 100, 150, this); g.setColor(Color.RED); g.drawRect(0, 0, getWidth(), getHeight()); FontMetrics fm = g.getFontMetrics(); String text = "Local 0x0"; g.drawString(text, 0, fm.getAscent()); } } } </code></pre> <p>With this example, I was able to get the <code>paintCount</code> to 3640 BEFORE I even touched the frame.</p> <p>Doing image loading in any <code>paint</code> method is also a bad idea. It's expected that <code>paint</code> methods should return as quickly as possible, failing to do so will reduce the performance of your program.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload