簡體   English   中英

Java Paint方法不繪畫?

[英]Java Paint Method Doesn't Paint?

我正在研究一個簡單的小擺動組件,我正在撕扯我的頭發試圖弄清楚為什么我的油漆方法不起作用。

這個組件背后的想法是它是一個帶標簽的小型JPanel。 背景(標簽后面)應該是白色的,左側有一個彩色矩形表示兩個測量值的比率:“實際”和“預期”。

如果你有一堆這些組件垂直對齊,它們會形成一個由水平條組成的條形圖。

這種事情應該是超級簡單的。

無論如何,這是代碼:

package com.mycompany.view;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;

import javax.swing.JLabel;
import javax.swing.JPanel;

public class BarGraphPanel extends JPanel {

   private static final Color BACKGROUND = Color.WHITE;
   private static final Color FOREGROUND = Color.BLACK;

   private static final Color BORDER_COLOR = new Color(229, 172, 0);
   private static final Color BAR_GRAPH_COLOR = new Color(255, 255, 165);

   private int actual = 0;
   private int expected = 1;

   private JLabel label;

   public BarGraphPanel() {
      super();
      label = new JLabel();
      label.setOpaque(false);
      label.setForeground(FOREGROUND);
      super.add(label);
      super.setOpaque(true);
   }

   public void setActualAndExpected(int actual, int expected) {
      this.actual = actual;
      this.expected = expected;
   }

   @Override
   public void paint(Graphics g) {

      double proportion = (expected == 0) ? 0 : ((double) actual) / expected;
      Rectangle bounds = super.getBounds();

      g.setColor(BACKGROUND);
      g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);

      g.setColor(BAR_GRAPH_COLOR);
      g.fillRect(bounds.x, bounds.y, (int) (bounds.width * proportion), bounds.height);

      g.setColor(BORDER_COLOR);
      g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);

      label.setText(String.format("%s of %s (%.1f%%)", actual, expected, proportion * 100));
      super.paint(g);
      g.dispose();
   }

}

這是簡單的測試工具:

package com.mycompany.view;

import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.UIManager;

public class MyFrame extends JFrame {

   public MyFrame() {
      super();
      super.setLayout(new GridLayout(3, 1));
      super.setPreferredSize(new Dimension(300, 200));

      BarGraphPanel a = new BarGraphPanel();
      BarGraphPanel b = new BarGraphPanel();
      BarGraphPanel c = new BarGraphPanel();

      a.setActualAndExpected(75, 100);
      b.setActualAndExpected(85, 200);
      c.setActualAndExpected(20, 300);

      super.add(a);
      super.add(b);
      super.add(c);
   }

   public static void main(String[] args) {
      javax.swing.SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGUI();
         }
      });
   }

   public static void createAndShowGUI() {

      try {
         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      } catch (Throwable t) { }

      MyFrame frame = new MyFrame();
      frame.pack();
      frame.setVisible(true);
   }

}

測試工具創建一個簡單的框架,然后添加其中三個控件。

標簽全部正確呈現,這向我指示實際調用了paint()方法,但矩形未被繪制到Graphics對象。

我究竟做錯了什么?

為什么Swing編程太吸引人了?


這是我的最終代碼。 謝謝,大家,謝謝你的幫助!

public void paintComponent(Graphics g) {

   double proportion = (expected == 0) ? 0 : ((double) actual) / expected;

   Rectangle bounds = super.getBounds();

   g.setColor(BACKGROUND);
   g.fillRect(0, 0, bounds.width, bounds.height);

   g.setColor(BAR_GRAPH_COLOR);
   g.fillRect(0, 0, (int) (bounds.width * proportion), bounds.height);

   g.setColor(BORDER_COLOR);
   g.drawRect(0, 0, bounds.width - 1, bounds.height - 1);

   FontMetrics metrics = g.getFontMetrics();
   String label = String.format("%s of %s (%.1f%%)", actual, expected, proportion * 100);
   Rectangle2D textBounds = metrics.getStringBounds(label, g);

   g.setColor(FOREGROUND);
   g.drawString(label, 5, (int) ((bounds.height + textBounds.getHeight()) / 2));
}

我想你在評論中幾乎已經回答了你自己的問題,以及大衛的回答。 paint(Graphics g)更改為paintComponent(Graphics g)並刪除方法的最后兩行,你應該沒問題。

編輯:奇怪的是,這只適用於三者中的第一個欄。 正在進行更多測試......

順便說一下,邊框繪制代碼中有一個一個一個錯誤。 它應該是:

g.setColor(BORDER_COLOR);
g.drawRect(bounds.x, bounds.y, bounds.width - 1, bounds.height - 1);

EDIT2:好的,明白了。 您的完整paintComponent方法應如下所示:

@Override
public void paintComponent(Graphics g) {
    double proportion = (expected == 0) ? 0 : ((double) actual) / expected;
    Rectangle bounds = super.getBounds();
    g.setColor(BACKGROUND);
    g.fillRect(0, 0, bounds.width, bounds.height);
    g.setColor(BAR_GRAPH_COLOR);
    g.fillRect(0, 0, (int) (bounds.width * proportion), bounds.height);
    g.setColor(BORDER_COLOR);
    g.drawRect(0, 0, bounds.width-1, bounds.height-1);
    label.setText(String.format("%s of %s (%.1f%%)", actual, expected, proportion * 100));
}

請注意,給予g.fillRect()g.drawRect()的坐標是相對於組件的,因此它們必須從(0,0)開始。

不,我無法幫助你解決你的最后一個問題,盡管我感到痛苦。 :)

在你的JPanel中,你調用了super.setOpaque(true)。 當您調用super.paint()並覆蓋您的重新綁定時,JPanel將完全填充后台。

不確定這是否是你的問題的根源,但在Swing你應該覆蓋paintComponent(Graphics2D)而不是......

如果有的話,我想你應該打電話給super.paint(g); 在你的方法的頂部,而不是在最底層。 超類可以在你的東西之上繪圖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM