首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在现有绘图上修复绘图

如何在现有绘图上修复绘图
EN

Stack Overflow用户
提问于 2019-10-10 03:26:46
回答 2查看 59关注 0票数 0

我的DrawPanel出了点问题。我想做一个烤架-它应该用参数来绘制-由用户通过定义行和冒号给出。

例如,我输入3行5个冒号(:),Swing应该绘制它。主要问题是,如果我在TextField中输入数字并按下绘制按钮,Swing会在旧格栅上绘制新格栅。此外,有时程序无法完成某些行或冒号,我不明白为什么。我已经添加了一些数字,比如rows-6,因为swing绘制的像素比他应该绘制的多了几个像素。也许你也知道这个问题的解决方案。

在这张图上你可以看到太多的线条。我用一条蓝线来表示这些线应该走多远。

DrawPanel (JPanel)

代码语言:javascript
复制
import java.awt.Graphics;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Serge Junk
 */
public class DrawPanel extends javax.swing.JPanel {

    /**
     * Creates new form DrawPanel
     * 
     */
    private int rows = 1;
    private int cols = 2;
    public DrawPanel() {
        initComponents();
    }

    @Override
   public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        int width = getWidth();
        int height = getHeight();

         // draw the rows
        int rowHt = (height / rows)-1;
        for (int i = 0; i <= rows; i++){
            g.drawLine(0, i * rowHt, width, i * rowHt);
        }


        // draw the columns
        int rowWid = (width / cols)-1;
        for (int i = 0; i <= cols; i++){
           g.drawLine(i * rowWid, 0, i * rowWid, height);
        }

    }

   public void setRows(int pRows){
       rows = pRows;
   }

    public void setCols(int pCols){
      cols = pCols;
   }
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        setPreferredSize(new java.awt.Dimension(300, 200));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );
    }// </editor-fold>                        


    // Variables declaration - do not modify                     
    // End of variables declaration                   
}

MainFrame (JFrame)

代码语言:javascript
复制
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Serge Junk
 */
public class MainFrame extends javax.swing.JFrame {

    /**
     * Creates new form MainFrame
     */
    public MainFrame() {
        initComponents();
    }

    public void updateView()
    {
        drawPanel1.repaint();
    }
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        drawPanel1 = new DrawPanel();
        jLabel1 = new javax.swing.JLabel();
        rowTextField = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        colsTextField = new javax.swing.JTextField();
        drawButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        javax.swing.GroupLayout drawPanel1Layout = new javax.swing.GroupLayout(drawPanel1);
        drawPanel1.setLayout(drawPanel1Layout);
        drawPanel1Layout.setHorizontalGroup(
            drawPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 600, Short.MAX_VALUE)
        );
        drawPanel1Layout.setVerticalGroup(
            drawPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 200, Short.MAX_VALUE)
        );

        jLabel1.setText("Lignes");

        jLabel2.setText("Colonnes");

        drawButton.setText("Draw");
        drawButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                drawButtonActionPerformed(evt);
            }
        });

        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.TRAILING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jLabel1)
                        .addGap(18, 18, 18)
                        .addComponent(rowTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jLabel2)
                        .addGap(18, 18, 18)
                        .addComponent(colsTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(25, 25, 25)
                        .addComponent(drawButton))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(28, 28, 28)
                        .addComponent(drawPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 600, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(26, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(41, 41, 41)
                .addComponent(drawPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 14, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(rowTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel2)
                        .addComponent(colsTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(drawButton)))
                .addContainerGap())
        );

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

    private void drawButtonActionPerformed(java.awt.event.ActionEvent evt) {                                           
        //E
        int row = Integer.valueOf(rowTextField.getText());
        int col = Integer.valueOf(colsTextField.getText());
        //T
        drawPanel1.setRows(row);
        drawPanel1.setCols(col);
        //S
        updateView();
    }                                          

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        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(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new MainFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JTextField colsTextField;
    private javax.swing.JButton drawButton;
    private DrawPanel drawPanel1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JTextField rowTextField;
    // End of variables declaration                   
}
EN

回答 2

Stack Overflow用户

发布于 2019-10-10 04:04:39

Netbeans把新的烤架画在了旧的烤架上。

paintComponent()方法中的第一个语句应该是:

代码语言:javascript
复制
super.paintComponent(g);

这将在您进行自定义绘制之前清除背景。

代码语言:javascript
复制
drawPanel1.setRows(row);
drawPanel1.setCols(col);
//S
updateView();

不需要使用updateView()方法。相反,setRows(...)setCols(...)方法都应该直接调用repaint()。也就是说,当组件的属性发生更改时,组件有责任重新绘制自身。

有时程序不能完成某些行或冒号,我不明白为什么。

代码语言:javascript
复制
int rowHt = height / rows-1;

使用公式时要明确,这样我们才能确切地知道您想要什么,而不是依赖于编译器。所以你应该使用:

代码语言:javascript
复制
int rowHt = (height / rows) - 1;

不要害怕为你的参数创建变量:

代码语言:javascript
复制
//g.drawLine(i * rowWid, 0, i * rowWid, height-5);
int xOffset = i * rowWidth;
int yEnd = height - 5;
g.drawLine(xOffset, 0, xOffset, yEnd);

这样,您就可以轻松地添加调试代码,以准确地查看用于绘制直线的值:

代码语言:javascript
复制
System.out.println(xOffset + " : " + yEnd);

现在,您应该能够确定您的逻辑是否正确。

票数 1
EN

Stack Overflow用户

发布于 2019-10-10 05:21:53

因此,正如camickr建议的那样,您不应该将任何隐藏变量添加到分区或行/高或cols /宽度,因为这是维护的噩梦。远离神奇的价值观!

DrawPanel.paintComponent必须做一些事情。

  1. 不要忘记调用super()
  2. 您需要确定线条粗细,以便知道要偏移多少。
  3. 将单位保留为浮点值,直到您需要将其设置为integers.
  4. Dispose。

此外,您不希望在它们的声明中设置实例变量,而是通过某种构造函数来设置。

另外,我添加了另外两个字段来控制线条宽度和颜色,如下所示。我还重新设计了布局,以便从代码维护的角度来看,它实际上是可读的。

跑步者

代码语言:javascript
复制
package question58310987;

import javax.swing.*;

public class Runner {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new MainFrame();

                setLookAndFeel(frame);

                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }

    private static void setLookAndFeel(JFrame frame) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            SwingUtilities.updateComponentTreeUI(frame);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }
    }
}

DrawPanel

代码语言:javascript
复制
package question58310987;

import java.awt.*;
import javax.swing.JPanel;

public class DrawPanel extends JPanel {
    private static final long serialVersionUID = 1889951852010548809L;

    private int rows;
    private int cols;
    private int thickness;
    private Color fgColor;
    private Color bgColor;

    private boolean dirty;
    private Stroke strokeRef;

    public DrawPanel() {
        this(3, 3);
    }

    public DrawPanel(int rows, int cols) {
        this(rows, cols, 1, Color.BLACK, null);
    }

    public DrawPanel(int rows, int cols, int thickness, Color fgColor, Color bgColor) {
        super();
        this.rows = rows;
        this.cols = cols;
        this.thickness = thickness;
        this.fgColor = fgColor;
        this.bgColor = bgColor;

        this.dirty = true; // initialized as true
    }

    private float getStrokeThickness(Graphics2D g2d) {
        Stroke stroke = g2d.getStroke();

        if (stroke instanceof BasicStroke) {
            return ((BasicStroke) stroke).getLineWidth();
        }

        return 1.0f;
    }

    /**
     * Re-evaluates the state of the properties.
     */
    protected void commitProperties(Graphics2D g2d) {
        if (dirty) {
            strokeRef = new BasicStroke(this.thickness);
            dirty = false;
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;

        commitProperties(g2d);

        g2d.setStroke(strokeRef);

        float lineSize = getStrokeThickness(g2d); // Calculate line thickness
        float halfStroke = lineSize > 2.0f ? lineSize / 2.0f : 1.0f;
        int width = this.getWidth();
        int height = this.getHeight();
        int maxWidth = (int) (width - halfStroke);
        int maxHeight = (int) (height - halfStroke);
        float yOffset = (((float) maxHeight - halfStroke) / (rows));
        float xOffset = (((float) maxWidth - halfStroke) / (cols));

        if (bgColor != null) {
            g2d.setColor(bgColor);
            g2d.fillRect(0, 0, getWidth(), getHeight());
        }

        g2d.setColor(fgColor);

        // Draw the horizontal lines
        for (int row = 0; row < rows; row++) {
            int y = (int) (row * yOffset + halfStroke);
            g2d.drawLine((int) halfStroke, y, maxWidth, y);
        }
        g2d.drawLine((int) halfStroke, maxHeight, maxWidth, maxHeight); // Draw the final horizontal line

        // Draw the vertical lines
        for (int col = 0; col < cols; col++) {
            int x = (int) (col * xOffset + halfStroke);
            g2d.drawLine(x, (int) halfStroke, x, maxHeight);
        }
        g2d.drawLine(maxWidth, (int) halfStroke, maxWidth, maxHeight); // Draw the final vertical line

        g2d.dispose(); // Clear changes
    }

    public String getFgColorHex() {
        return String.format("#%02X%02X%02X", fgColor.getRed(), fgColor.getGreen(), fgColor.getBlue());
    }

    public int getRows() {
        return rows;
    }

    public void setRows(int rows) {
        this.rows = rows;
    }

    public int getCols() {
        return cols;
    }

    public void setCols(int cols) {
        this.cols = cols;
    }

    public int getThickness() {
        return thickness;
    }

    public void setThickness(int thickness) {
        this.thickness = thickness;
        this.dirty = true;
    }

    public Color getFgColor() {
        return fgColor;
    }

    public void setFgColor(Color fgColor) {
        this.fgColor = fgColor;
    }

    public Color getBgColor() {
        return bgColor;
    }

    public void setBgColor(Color bgColor) {
        this.bgColor = bgColor;
    }
}

MainFrame

代码语言:javascript
复制
package question58310987;

import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;

public class MainFrame extends JFrame {
    private static final long serialVersionUID = -2796976952328960949L;
    private static final String DEFAULT_APP_TITLE = "Main Frame";

    private DrawPanel drawPanel;

    private JLabel rowLabel;
    private JTextField rowTextField;

    private JLabel colLabel;
    private JTextField colTextField;

    private JLabel thicknessLabel;
    private JTextField thicknessTextField;

    private JLabel colorLabel;
    private JTextField colorTextField;

    private JButton drawButton;

    public MainFrame() {
        this(DEFAULT_APP_TITLE);
    }

    public MainFrame(String title) {
        super(title);

        initialize();
        addChildren();
    }

    protected void initialize() {
        drawPanel = new DrawPanel();
        drawPanel.setThickness(6);
        drawPanel.setFgColor(Color.BLUE);
        drawPanel.setPreferredSize(new Dimension(600, 200));

        rowLabel = new JLabel("Rows");
        rowTextField = new JTextField(Integer.toString(drawPanel.getRows()), 3);

        colLabel = new JLabel("Columns");
        colTextField = new JTextField(Integer.toString(drawPanel.getCols()), 3);

        thicknessLabel = new JLabel("Thickness");
        thicknessTextField = new JTextField(Integer.toString(drawPanel.getThickness()), 3);

        colorLabel = new JLabel("Color");
        colorTextField = new JTextField(drawPanel.getFgColorHex(), 6);

        drawButton = new JButton("Draw");
        drawButton.addActionListener(evt -> drawButtonActionPerformed(evt));
    }

    protected void addChildren() {
        GridBagLayout verticalLayout = new GridBagLayout();
        GridBagConstraints gbc = new GridBagConstraints();

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets = new Insets(16, 16, 16, 16); // top, left, bottom, right

        getContentPane().setLayout(verticalLayout);
        getContentPane().add(drawPanel, gbc);

        FlowLayout horizontalLayout = new FlowLayout();
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(horizontalLayout);

        buttonPanel.add(rowLabel);
        buttonPanel.add(rowTextField);
        buttonPanel.add(Box.createHorizontalStrut(30));

        buttonPanel.add(colLabel);
        buttonPanel.add(colTextField);
        buttonPanel.add(Box.createHorizontalStrut(30));

        buttonPanel.add(thicknessLabel);
        buttonPanel.add(thicknessTextField);
        buttonPanel.add(Box.createHorizontalStrut(30));

        buttonPanel.add(colorLabel);
        buttonPanel.add(colorTextField);
        buttonPanel.add(Box.createHorizontalStrut(30));

        buttonPanel.add(drawButton);

        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.insets = new Insets(0, 16, 16, 16); // top, left, bottom, right

        getContentPane().add(buttonPanel, gbc);
    }

    private void drawButtonActionPerformed(ActionEvent evt) {
        int row = Integer.valueOf(rowTextField.getText().trim());
        int col = Integer.valueOf(colTextField.getText().trim());
        int thickness = Integer.valueOf(thicknessTextField.getText().trim());
        String colorHex = colorTextField.getText().trim();

        drawPanel.setRows(row);
        drawPanel.setCols(col);
        drawPanel.setThickness(thickness);
        drawPanel.setFgColor(hexToColor(colorHex));

        this.updateView();
    }

    public void updateView() {
        drawPanel.repaint();
    }

    /**
     * Supports both #FF0000 and #F00 formats.
     * 
     * @param hex a hexadecimal color value from #000000 -> #FFFFFF
     * @return
     */
    public static final Color hexToColor(String hex) {
        if (hex.startsWith("#")) {
            hex = hex.replace("#", "");
        }
        if (hex.length() == 3) {
            hex = splicePad(hex, 2);
        }
        int v = Integer.parseInt(hex, 16);
        int r = (v & 0xFF0000) >> 16;
        int g = (v & 0xFF00) >> 8;
        int b = (v & 0xFF);
        return new Color(r, g, b);
    }

    /**
     * Splices each character after itself n-number of times. 
     */
    public static final String splicePad(String str, final int repeat) {
        StringBuffer buff = new StringBuffer();

        for (char ch : str.toCharArray()) {
            for (int i = 0; i < repeat; i++) {
                buff.append(ch);
            }
        }

        return buff.toString();
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58310987

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档