0

您好,我在面板上绘制图片并将其添加到框架时遇到问题。

import java.awt.Graphics;
import java.awt.Image;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CardComponent extends JPanel {
int x;int y;
String[] str = {
           "D:\\Images\\ImageCards\\Clubs_Ace.png",
           "D:\\Images\\ImageCards\\Clubs_King.png",
           "D:\\Images\\ImageCards\\Clubs_Queen.png",
           "D:\\Images\\ImageCards\\Clubs_Jack.png",
           "D:\\Images\\ImageCards\\Clubs_10.png",
           "D:\\Images\\ImageCards\\Clubs_9.png",
           "D:\\Images\\ImageCards\\Clubs_8.png",
           "D:\\Images\\ImageCards\\Clubs_7.png",
           "D:\\Images\\ImageCards\\Clubs_6.png",
           "D:\\Images\\ImageCards\\Clubs_5.png",
           "D:\\Images\\ImageCards\\Clubs_4.png",
           "D:\\Images\\ImageCards\\Clubs_3.png",
           "D:\\Images\\ImageCards\\Clubs_2.png",
           "D:\\Images\\ImageCards\\Diamonds_Ace.png",
           "D:\\Images\\ImageCards\\Diamonds_King.png",
           "D:\\Images\\ImageCards\\Diamonds_Queen.png",
           "D:\\Images\\ImageCards\\Diamonds_Jack.png",
           "D:\\Images\\ImageCards\\Diamonds_10.png",
           "D:\\Images\\ImageCards\\Diamonds_9.png",
           "D:\\Images\\ImageCards\\Diamonds_8.png",
           "D:\\Images\\ImageCards\\Diamonds_7.png",
           "D:\\Images\\ImageCards\\Diamonds_6.png",
           "D:\\Images\\ImageCards\\Diamonds_5.png",
           "D:\\Images\\ImageCards\\Diamonds_4.png",
           "D:\\Images\\ImageCards\\Diamonds_3.png",
           "D:\\Images\\ImageCards\\Diamonds_2.png",
           "D:\\Images\\ImageCards\\Hearts_Ace.png",
           "D:\\Images\\ImageCards\\Hearts_King.png",
           "D:\\Images\\ImageCards\\Hearts_Queen.png",
           "D:\\Images\\ImageCards\\Hearts_Jack.png",
           "D:\\Images\\ImageCards\\Hearts_10.png",
           "D:\\Images\\ImageCards\\Hearts_9.png",
           "D:\\Images\\ImageCards\\Hearts_8.png",
           "D:\\Images\\ImageCards\\Hearts_7.png",
           "D:\\Images\\ImageCards\\Hearts_6.png",
           "D:\\Images\\ImageCards\\Hearts_5.png",
           "D:\\Images\\ImageCards\\Hearts_4.png",
           "D:\\Images\\ImageCards\\Hearts_3.png",
           "D:\\Images\\ImageCards\\Hearts_2.png",
           "D:\\Images\\ImageCards\\Spades_Ace.png",
           "D:\\Images\\ImageCards\\Spades_Ace.png",
           "D:\\Images\\ImageCards\\Spades_King.png",
           "D:\\Images\\ImageCards\\Spades_Queen.png",
           "D:\\Images\\ImageCards\\Spades_Jack.png",
           "D:\\Images\\ImageCards\\Spades_10.png",
           "D:\\Images\\ImageCards\\Spades_9.png",
           "D:\\Images\\ImageCards\\Spades_8.png",
           "D:\\Images\\ImageCards\\Spades_7.png",
           "D:\\Images\\ImageCards\\Spades_6.png",
           "D:\\Images\\ImageCards\\Spades_5.png",
           "D:\\Images\\ImageCards\\Spades_4.png",
           "D:\\Images\\ImageCards\\Spades_3.png",
           "D:\\Images\\ImageCards\\Spades_2.png"      
           };
   Image img;
     public CardComponent(int x,int y) {
         setOpaque(false);
         this.x = x;
         this.y = y;
         setSize(100,150);
         setVisible(true);


     }
     public void paint(Graphics g) {
         super.paint(g);
         Random r = new Random();
         String s = "";
         s = str[r.nextInt(str.length)];
         img = getToolkit().getImage(s);
         g.drawImage(img,this.x , this.y, 100, 150, this);
     }
     public static void main(String[] args) {
         CardComponent cc = new CardComponent(10,150);
         JFrame jfrm = new JFrame();
         jfrm.setSize(100, 150);
         jfrm.setVisible(true);
         jfrm.getContentPane().add(cc);
     }
 }

在类上是主要问题(无法绘制卡片)。我将这个东西添加到主框架(代码下)。我在每个类中添加方法 main 只是为了检查它是否工作正常。导入 java.awt.Button;导入 java.awt.Color;导入 java.awt.event.ActionEvent;导入 java.awt.event.ActionListener;

  import javax.swing.JFrame;
  import javax.swing.JLabel;
  import javax.swing.JPanel;
  import javax.swing.JSlider;
  import javax.swing.event.ChangeEvent;
  import javax.swing.event.ChangeListener;


  public class PanelButtons extends JPanel{
Button but1;
Button but2;
    Button but3;
JLabel jlab;
JSlider jsl;
public PanelButtons() {
     setLayout(null);  
     Color c = new Color(0,120,0);
     setSize(700,200);
     setLocation(0,0);
     setOpaque(false);
     but1 = new Button("Check");
     but1.setBackground(Color.CYAN);
     but1.setLocation(660, 350);
     but1.setBounds(683, 650, 70, 40);
     add(but1);
     but2 = new Button("Fold");
     but2.setBackground(Color.CYAN);
     but2.setLocation(660, 350);
     but2.setBounds(753, 650, 70, 40);
     add(but2);
     but3 = new Button("Bet");
     but3.setBackground(Color.CYAN);
     but3.setLocation(660, 350);
     but3.setBounds(823, 650, 70, 40);
     add(but3);
     int money = Player.PremierMoney();
     jsl = new JSlider(0,1000);
     jsl.setMajorTickSpacing(50);
     jsl.setMinorTickSpacing(10);
     jsl.setLabelTable(jsl.createStandardLabels(100));
     jsl.setPaintTicks(true);
     jsl.setPaintLabels(true);
     jsl.setSize(400, 150);
     jsl.setBackground(c);
     jlab = new JLabel("Ваша ставка"+jsl.getValue());
     jsl.addChangeListener(new ChangeListener() {
        @Override
        public void stateChanged(ChangeEvent ce) {
            if(jsl.getValueIsAdjusting()) return;
            jlab.setText("Ваша ставка:"+jsl.getValue());

        }

     });
     jlab.setHorizontalTextPosition(JLabel.CENTER);
     jlab.setVerticalAlignment(JLabel.BOTTOM);
     jsl.setLocation(900,600);
     jlab.setLocation(150,150);
     add(jsl);
     add(jlab);
     but2.addActionListener(new ActionListener() {


         @Override
        public void actionPerformed(ActionEvent e) {
             but1.setEnabled(false);
             but2.setEnabled(false);
             but3.setEnabled(false);

        }
     });
}

public static void main(String[] args) {
    JFrame jfrm = new JFrame("Some frame");
    jfrm.setSize(200, 200);
    PanelButtons pb = new PanelButtons();
    jfrm.setContentPane(pb);
    jfrm.setVisible(true);
    jfrm.setDefaultCloseOperation(jfrm.EXIT_ON_CLOSE);
}
   }

此类描述按钮和滑块。导入 java.awt.Color;导入 javax.swing.JFrame;

    public class Images extends JFrame{
   Images() {
      // CardComponent cc = new CardComponent(530,550);
       PanelButtons pb = new PanelButtons();
       Color c = new Color(0,120,0);
    //  cc.setBounds(530, 550, 100, 150);
      setSize(1366,750); 
      setBackground(c);
      setContentPane(pb);
    //  setContentPane(cc);
      setVisible(true);
   }    




   public static void main(String[] args) {
       Images im = new Images();
       im.setResizable(false);
       im.setDefaultCloseOperation(EXIT_ON_CLOSE);
   }
    }

这是我添加面板的主框架。所以主要问题是我在哪里画卡。感谢帮助。

4

2 回答 2

3

整个程序有很多问题,null布局的选择很重要,这会给你带来很多问题。

但是,您面临的重大问题在于您的paint方法

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);
}

这种方法存在三个问题。

  1. 你应该压倒一切paintComponent,它是一种更安全的执行自定义绘画的方法。
  2. 您在每个绘画周期中随机重新生成图像。您必须记住,您的组件可能因多种原因而被绘制,并且大多数超出您的控制范围。这意味着每次绘制组件时,都会加载一个新图像。您应该在构建组件时将单个图像分配给组件并绘制该图像。
  3. 传递给您的组件的Graphics上下文已被翻译,因此点 0x0 将位于组件的左上角。这意味着,所有的绘画都是相对的。

您的代码执行此操作...

g.drawImage(img, this.x, this.y, 100, 150, this);

这意味着,图像将在相对于组件的顶部/左侧位置的 x/y 像素处绘制。相反,您应该在 0x0 位置周围进行绘画。

在您的示例中,您还可以

jfrm.setVisible(true);
jfrm.getContentPane().add(cc);

这通常是个坏主意,你应该切换这两个语句,否则看起来像什么都没有画。

您可能会发现值得一读

用一个简单的例子更新

此示例旨在演示paint方法可以采用的命中数量以及局部坐标空间的概念。

在此处输入图像描述

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 < 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());
        }
    }
}

在这个例子中,paintCount我什至在触摸框架之前就可以达到 3640。

以任何方法加载图像paint也是一个坏主意。方法应该paint尽快返回,否则会降低程序的性能。

于 2013-04-06T10:10:21.837 回答
0

我对你的代码有点困惑,我没有看到一个CardComponent对象,你必须实例化你的CardComponent类的一个对象,然后将它添加到你的JFrameJFrame像这样的组件中......

Images im = new Images();
PanelButtons pb = new PanelButtons();
CardComponent cc = new CardComponent(x, y);
im.setContentPane(pb);
pb.setLayout(new BorderLayout());
pb.add(cc, BorderLayout.CENTER);

这不是一个有效的程序,但希望你能明白。而且我只是浏览了代码,所以我可能错过了实例化CardComponent对象的位置,所以如果您仍然遇到问题,请尝试以这种方式加载图像......

public void paint(Graphics g) {
     super.paint(g);
     Random r = new Random();
     String s = "";
     s = str[r.nextInt(str.length)];
     img = ImageIcon(s).getImage();
     g.drawImage(img,this.x , this.y, 100, 150, this);
 }

我刚刚运行了你的代码,我还有一个建议。在CardComponent构造函数中使用设置boundssetBounds(x, y, 100, 150)方法然后从左上角(0, 0)到右下角(100, 150)或者(getWidth(), getHeight())绘制图像。

希望这会有所帮助,祝你好运。

于 2013-04-06T09:39:42.997 回答