Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <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>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. COThanks , I'll read it , but I have few questions.Why setLayout(null) is a bad idea?I know that you need to do some more things then ,but i think it can organize better my interface.I agree that painting 1 image of 1 component is a safer idea ,but I have 52 cards, 52 components ,52 classes ,sounds creepy(or maybe i didn't understand you right).But I didn't understand 3 point ,can you explain pls?Next about image , thanks,but if I put this image into a component and then into a panel with coor (150,150) and image would draw coor(150,150).Would image draw with coor(300,300) ?Thanks for helping!
      singulars
    2. COLayout managers reduce complexity and take into consideration differences in how different platforms render content. The question is, do you want to program the game or the layout management? The Swing API is designed around the use of layout managers, so you're throwing away a large segment of the API. The problem with the way your paint routine is setup, is that each time the `CardComponent` is painted, it paints a new, random image. This can be done in response to the frame been resized, the mouse been moved over the component, dozens of other issues that you have no control over
      singulars
    3. COMost modern PC's have, what, 4mb of RAM, I don't think memory is an issue. If you're really worried about, you should only be rendering those cards that are visible anyway, what, maybe 12? Point 3. All painting of a component (within the `paint` method) is done so that the x/y position of 0x0 is the top/left corner of the component. Your setup has the image been painted at 10x150, while the component is only ever 100x150 in size, that means, the images are been rendered outside the component
      singulars
 

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