java - 我用 Swing 绘制的旋钮很难看。为什么?

标签 java swing

我正在绘制一个旋钮作为一个组件,并且我正在使用 swing。结果看起来不错,但是当我单击旋钮并移动鼠标(向上或向下)来更改旋钮位置时,重新绘制的旋钮很难看,就好像有两层叠加一样。更重要的是,我只得到了“小尺寸”旋钮的结果。如果我放大画面,这种丑陋的效果就会消失。有人可以向我解释一下发生了什么以及如何改进我的旋钮吗?

非常感谢那些帮助我的人。

这是我的代码:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Line2D;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class Knob extends JPanel implements MouseListener {
int length, originX, originY, centerX, centerY, width, height, diameter, squareLength;
int minorTick, majorTick, xTick, yTick, xCursor, yCursor;
int xMouse, yMouse, xMouseOrigin, yMouseOrigin;
float yDeltaMouse;
double angleOrigin, angleRange, angle;
double cursorValue;
double initialCursorValue;
Color backgroundColor, knobColor;
boolean mousePressed;
Thread t;
private double knobValue;
private String title = new String("");
private int titleWidth;

Knob (double initialValue, Color c, int majorTick, int minorTick) {
    //System.out.println("Knob");
    cursorValue=initialCursorValue=initialValue;
    knobColor =c;       
    this.majorTick=majorTick;
    this.minorTick=minorTick;       

    this.addMouseListener(this);
}

Knob (double initialValue, Color c, int majorTick, int minorTick, String title) {
    //System.out.println("Knob");
    cursorValue=initialCursorValue=initialValue;
    knobColor =c;       
    this.majorTick=majorTick;
    this.minorTick=minorTick;
    this.title=title;

    this.addMouseListener(this);
}

public void paintComponent (Graphics g) {
    width=this.getWidth()/10*10;
    height=this.getHeight()/10*10;

    Graphics2D g2D = (Graphics2D)g;
    System.setProperty("awt.useSystemAAFontSettings", "on");
    System.setProperty("swing.aatext", "true");
    g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    if (width>height) {
        length=height;
    } else {
        length=width;
    }
    centerX=width/2;
    centerY=height/2;

    g.setColor(Color.BLACK);
    squareLength = (int )(length*0.9);
    originX=(width-squareLength)/2;
    originY=(height-squareLength)/2;

    /*
    //-45 = (-(Math.PI)/4)
    angleOrigin= -45;
    // 270 = (3*(Math.PI)/2)
    angleRange=270;
    //g.drawRect(originX, originY, squareLength, squareLength);
    //g.fillArc(originX, originY, squareLength, squareLength, (int)angleOrigin, (int)angleRange);
    for (int i=0; i<minorTick ; i++) {
        angle=((i*angleRange/(minorTick-1))+angleOrigin)-7;
        //System.out.println(angle*360/(2*Math.PI));
        xTick= (int) (centerX+Math.cos(angle)*squareLength/2);
        yTick= (int) (centerY-Math.sin(angle)*squareLength/2);
        //g.drawLine(centerX, centerY, xTick, yTick);
        //g.fillArc(originX, originY, squareLength, squareLength, (int)angle, (int)14);
    }
    */

    angleOrigin=-(Math.PI)/4;
    angleRange=3*(Math.PI)/2;       
    g2D.setStroke(new BasicStroke(length/50+1));        
    for (int i=0; i<minorTick ; i++) {
        angle=i*angleRange/(minorTick-1)+angleOrigin;
        //System.out.println(angle*360/(2*Math.PI));
        xTick= (int) (centerX+Math.cos(angle)*squareLength/2);
        yTick= (int) (centerY-Math.sin(angle)*squareLength/2);
        //g.drawLine(centerX, centerY, xTick, yTick);
        g2D.draw (new Line2D.Float(centerX, centerY, xTick, yTick));
    }

    backgroundColor = this.getBackground();
    g.setColor(backgroundColor);
    diameter=(int)(length*0.8);
    originX=(width-diameter)/2;
    originY=(height-diameter)/2;
    g.fillOval(originX, originY, diameter, diameter);


    /*
    RadialGradientPaint gp;
    Point2D center= new Point2D.Float(width/2, height/2);
    diameter=(int)(length*0.75);
    originX=(width-diameter)/2;
    originY=(height-diameter)/2;
    float radius=diameter/2;        
    float[] dist = {0.7f, 1f};
    Color[] colors = {Color.BLUE, Color.GRAY};
    gp=new RadialGradientPaint(center, radius, dist, colors);
    g2D.setPaint(gp);       
    g2D.fillOval(originX,originY,diameter,diameter);
    */
    diameter=(int)(length*0.75);
    originX=(width-diameter)/2;
    originY=(height-diameter)/2;
    g.setColor(Color.GRAY);
    g.fillOval(originX,originY,diameter,diameter);

    diameter=(int)(length*0.7);
    originX=(width-diameter)/2;
    originY=(height-diameter)/2;
    g.setColor(knobColor);
    g.fillOval(originX,originY,diameter,diameter);


    g2D.setStroke(new BasicStroke(length/50+3));
    angle=(2*Math.PI)*(0.75-cursorValue*0.75)+angleOrigin;
    xCursor= (int) (centerX+Math.cos(angle)*length*0.35);
    yCursor= (int) (centerY-Math.sin(angle)*length*0.35);
    g.setColor(Color.GRAY);
    g2D.draw (new Line2D.Float(centerX, centerY, xCursor, yCursor));

    g2D.rotate(Math.toRadians(270.0));
    g.setFont(new Font(g.getFont().getFontName(),Font.PLAIN,this.getHeight()/3));
    titleWidth=g.getFontMetrics().stringWidth(title);
    g2D.drawString(title,-this.getHeight()+titleWidth/3,this.getHeight()/4);        
    //System.out.println(titleWidth);
    //System.out.println(this.getHeight()*(-70)/100+" - "+this.getHeight());
}

@Override
public void mouseClicked(MouseEvent arg0) {
    // TODO Auto-generated method stub
    //System.out.println("Bouton : "+arg0.getButton());

}

@Override
public void mouseEntered(MouseEvent arg0) {
    // TODO Auto-generated method stub

}

@Override
public void mouseExited(MouseEvent arg0) {
    // TODO Auto-generated method stub

}

@Override
public void mousePressed(MouseEvent arg0) {
    // TODO Auto-generated method stub
    //System.out.println("Bouton : "+arg0.getButton());
    PointerInfo pointer = MouseInfo.getPointerInfo();
    Point mouseLocation = pointer.getLocation();
    xMouseOrigin = (int) mouseLocation.getX();
    yMouseOrigin = (int) mouseLocation.getY();
    if (arg0.getButton()==MouseEvent.BUTTON1) {
        mousePressed=true;
        t= new Thread(new TrackPosition());
        t.start();
    } else if (arg0.getButton()==MouseEvent.BUTTON3) {
        cursorValue=initialCursorValue;
        repaint();
        knobValue=cursorValue;
    }       
}

@Override
public void mouseReleased(MouseEvent arg0) {
    // TODO Auto-generated method stub
    mousePressed=false;
    //System.out.println("Mouse released");     
    repaint();      
}

class TrackPosition implements Runnable {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        while (mousePressed==true) {
            PointerInfo pointer = MouseInfo.getPointerInfo();
            Point mouseLocation = pointer.getLocation();
            yMouse = (int) mouseLocation.getY();
            yDeltaMouse=(float)(yMouse-yMouseOrigin)/100;
            cursorValue=cursorValue+yDeltaMouse;
            yMouseOrigin=yMouse;
            if (cursorValue >=1) {
                cursorValue=1;
            } else if (cursorValue <= 0) {
                cursorValue=0;
            }
            //This repaint is a problem if I "uncomment" it
            repaint();
            knobValue=cursorValue;
        }           
    }       
}

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub
    JFrame frame = new JFrame();
    frame.setSize(300,70);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setContentPane(new Knob(0.5, new Color(0,255,0,255), 3, 9, "Gain"));
    frame.setVisible(true);
}

}

最佳答案

您错过了从 JComponent 调用 paintComponent(Graphics g) 方法。

按如下方式更改代码即可解决问题。

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

关于java - 我用 Swing 绘制的旋钮很难看。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34631699/

相关文章:

java - 如何在应用程序退出之前使文本字段失去焦点?

java - 在 fragment 之间切换时保存并重新加载 edittext 值

java - 从故障转储确定 Eclipse 的版本

java - ProcessBuilder 的命令有限制吗?

Java、泛型和继承

java - 带路径压缩的加权快速联合

java - apache服务器在java swing应用程序(3层)中的作用是什么?

java - 特定行和列的自定义单元格渲染器

java - 如何在GroupLayout Java中设置Jframe背景图片

java - 如何获取所有 JCheckBox 对象的句柄以便循环?