سؤال

أنا أعمل على عنصر تأرجح صغير وبسيط، وأقوم بتمزيق شعري محاولًا معرفة سبب عدم نجاح طريقة الطلاء الخاصة بي.

الفكرة وراء هذا المكون هي أنه عبارة عن لوحة 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);
   }

}

يقوم جهاز الاختبار بإنشاء إطار بسيط ثم يضيف ثلاثة من عناصر التحكم هذه.

تم عرض جميع التسميات بشكل صحيح، مما يشير إلى أنه يتم استدعاء طريقة الطلاء () بالفعل، ولكن لا يتم رسم المستطيلات إلى كائن الرسومات.

ما الخطأ الذي افعله؟

ولماذا تمتص برمجة 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);

تحرير 2: حسنا، حصلت عليه.الخاص بك كامل 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 (صحيح). وJPanel هو الذهاب الى ملء تماما في الخلفية عند استدعاء super.paint ()، والكتابة retangles الخاص بك.

ولست متأكدا إذا كان هذا هو مصدر المشكلة، ولكن في سوينغ كنت من المفترض أن تجاوز paintComponent(Graphics2D) بدلا من ذلك ...

وإذا كان أي شيء، أعتقد أن عليك أن تكون الدعوة super.paint (ز)؛ في الجزء العلوي من طريقة، وليس في الجزء السفلي جدا. فمن الممكن الفائقة يقترب على رأس الأشياء الخاصة بك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top