绘图 window 空白 window

Drawing in window and blank window

我有一个程序可以将点添加到列表中并计算由这些点创建的图形的面积。 我无法添加 window 的屏幕,但我将解释发生了什么。 我在 Java 中创建了 JFrameForm 并在左侧放置了一些标签和文本字段,在右侧留下了一些 space 以绘制我添加到列表中的点。 问题是每当我画任何东西时 windows 都会变得空白。单击标签时,标签会消失,文本字段会出现。

我的第二个问题是如何用 paint() 函数以外的方式绘制某物? 假设我将这些点添加到列表中,当我单击一个按钮时,我希望它在我的 window 中的右侧绘制(使用 drawOval() 或推荐我其他功能)。

//全部导入

public class NewJFrame 扩展 javax.swing.JFrame {

public void paint(Graphics g) {
    g.drawLine(600, 150, 700, 150);
}

public NewJFrame() {
    initComponents();
}


@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jLabel1 = new javax.swing.JLabel();
    jLabel2 = new javax.swing.JLabel();
    jTextField1 = new javax.swing.JTextField();
    jTextField2 = new javax.swing.JTextField();
    jButton1 = new javax.swing.JButton();
    jButton2 = new javax.swing.JButton();
    jLabel3 = new javax.swing.JLabel();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jLabel1.setLabelFor(jTextField1);
    jLabel1.setText("X: ");
    jLabel1.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));

    jLabel2.setLabelFor(jTextField2);
    jLabel2.setText("Y:");
    jLabel2.setName("labelY"); // NOI18N

    jTextField1.setName("textX"); // NOI18N

    jTextField2.setName("textY"); // NOI18N
    jTextField2.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jTextField2ActionPerformed(evt);
        }
    });

    jButton1.setText("ADD");
    jButton1.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
    jButton1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton1ActionPerformed(evt);
        }
    });

    jButton2.setText("PROCEED");
    jButton2.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
    jButton2.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton2ActionPerformed(evt);
        }
    });

    jLabel3.setFont(new java.awt.Font("Tahoma", 0, 36)); // NOI18N

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jLabel1)
                            .addGap(18, 18, 18)
                            .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 126, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jLabel2)
                            .addGap(18, 18, 18)
                            .addComponent(jTextField2))))
                .addGroup(layout.createSequentialGroup()
                    .addGap(6, 6, 6)
                    .addComponent(jButton1)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(jButton2))
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 316, javax.swing.GroupLayout.PREFERRED_SIZE)))
            .addContainerGap(419, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(86, 86, 86)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jLabel1))
            .addGap(26, 26, 26)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jLabel2))
            .addGap(32, 32, 32)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jButton1)
                .addComponent(jButton2))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 33, Short.MAX_VALUE)
            .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(24, 24, 24))
    );

    jLabel1.getAccessibleContext().setAccessibleName("labelX");
    jLabel2.getAccessibleContext().setAccessibleName("labelY");
    jTextField1.getAccessibleContext().setAccessibleName("textX");
    jTextField2.getAccessibleContext().setAccessibleName("textY");

    pack();
}// </editor-fold>                        

private void jTextField2ActionPerformed(java.awt.event.ActionEvent evt) {                                            
    // TODO add your handling code here:
}                                           
protected List<Point> list = new ArrayList<>();
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    try {        
        list.add(new Point( Integer.valueOf(jTextField1.getText()), Integer.valueOf(jTextField2.getText()) ));
    }catch(NumberFormatException e) {
        System.out.println("Error");
    }
    jTextField1.setText("");
    jTextField2.setText("");
}                                        

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    TwoLists two = new TwoLists(list);

    list = two.sortLists();

    jLabel3.setText("Area: " + Triangularyzacja.countFigureArea(list));
}                                        


public static void main(String args[]) {

    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>


    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new NewJFrame().setVisible(true);
        }
    });


}

// Variables declaration - do not modify                     
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JTextField jTextField1;
private javax.swing.JTextField jTextField2;
// End of variables declaration                   

}

这是代码(抱歉样式,但不知道如何粘贴更好)。 它全部由 NetBeans 生成,尽管 paint() 函数在开头并且它破坏了所有布局(它变得空白)。我还有 8 classes,其中包含机械代码。

首先,您需要一个组件绘制到 JPanel 或 JLabel 或其他任何东西上,而不是仅仅绘制在框架本身上(组件是否透明(不透明 = true)并不重要)。这将使您更好地控制未来发生的事情。

假设它是您放置在 GUI 窗体上的 JPanel(例如 jPanel1)并且您想要在其上绘制,您可以创建并使用这样的方法(名称任何你喜欢的方法:):

public static void drawMyStuff(JPanel panel) {
    // Declare and initialize a graphics object 
    // based on the supplied component.
    Graphics g = panel.getGraphics();

    // Set the color we want to use...
    g.setColor(Color.red);

    // Draw a red line horizontally through the 
    // center of the supplied component.
    g.drawLine(0, panel.getHeight()/2, panel.getWidth(), panel.getHeight()/2);

    // Close the Graphics object, we don't need it anymore.
    g.dispose();

    // Update the supplied component so as
    // to display what we've drawn.
    panel.revalidate(); 
}

你可以把这个方法放在哪里? 在您的项目中的任何 public class。

您将如何以及在何处调用此方法?

drawMyStuff(jPanel1);

您可以从任何地方调用此方法(因为它是一个 public 方法),只要可以获取对提供的组件的引用。

基本上这意味着您应该从您提供的 JPanel 所在的同一个 Class 中调用此方法,当然除非 JPanel 本身也是 public。

您可能想从 JButton actionPerformed 事件调用此方法:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    drawMyStuff(jPanel1);
}

如果您更喜欢在 JLabel 上绘图,则只需更改方法声明中的参数声明,

例如:

public static void drawMyStuff(JLabel panel) {....}

或者如果您确实想直接在 JFrame 上绘图,那么:

public static void drawMyStuff(JFrame panel) {....} 

如果您打算直接在 JFrame 表单上绘图,那么您可以从扩展的 JFrame Class 中调用此方法,例如:

drawMyStuff(this);

现在,目前 drawMyStuff() 方法不是很实用。它只是在我提供的组件的中心画了一条红线。如果我想根据应用程序中的某些条件不时更改颜色和/或线长怎么办?

在这种情况下,我们需要向方法声明中添加更多参数,并使用这些参数根据需要修改绘制的线条。让我们在我们的方法中添加一些参数来处理颜色,线起点 (in pixels) 和线的终点 (in pixels)。这是我们的新方法声明:

public static void drawMyStuff(JPanel panel, Color color, int startPoint, int endPoint) { ... }

正如您在上面的方法声明中看到的那样,我们仍然有我们的组件对象,在本例中是一个 JPanel,我们需要它以便我们的方法知道要绘制什么.我们还添加了一个名为 color 的 Color 对象参数,这样我们就可以提供我们想要的线条颜色。

我们还添加了两个名为 startPointendPoint 的整数类型参数。 startPoint 参数将告诉我们的方法在提供的组件内沿着 X 轴(水平面)开始彩色线的位置。 endPoint 参数将告诉我们的方法在同一水平轴上结束彩色线的位置。这两个参数决定了我们线条的实际长度(以像素为单位)(endPoint - startPoint = 以像素为单位的长度)。

现在我们有了额外的参数,让我们修改我们的方法代码主体以容纳这些完全相同的参数:

public static void drawMyStuff(JPanel panel, Color color, int startPoint, int endPoint) {
    // Declare and initialize a graphics object 
    // based on the supplied JPanel.
    Graphics g = panel.getGraphics();

    // Set the color we want to use...
    g.setColor(color);  // here we supply our color parameter

    // Draw a red line horizontally through the 
    // center of the supplied JPanel. Notice our 
    // new startPoint and endPoint parameters are
    // supplied here.
    g.drawLine(startPoint, panel.getHeight()/2, endPoint, panel.getHeight()/2);

    // Close the Graphics object, we don't need it anymore.
    g.dispose();

    // Update the supplied JPanel so as
    // to display what we've drawn.
    panel.revalidate(); 
}

要调用这个方法,我们会这样做:

drawMyStuff(jPanel1, Color.blue, 20, 80);

这将沿 jPanel1 的中心水平绘制一条 60 像素长的蓝色线,从左边缘开始 20 像素。

我知道画一条简单的线不是您想做的,但您现在知道如何轻松修改此方法以使其随心所欲。