我正在绘制一个旋钮作为组件,并且正在使用秋千。结果似乎还可以,但是当我单击旋钮并向上或向下移动鼠标以更改旋钮位置时,重新绘制的旋钮很难看,好像有两层叠加在一起。而且,仅对于旋钮的“小尺寸”,我才有此结果。如果我扩大框架,这种丑陋的效果就会消失。有人可以向我解释发生了什么以及如何改进旋钮吗?
非常感谢那些会帮助我的人。
这是我的代码:
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);
}
}
最佳答案
您错过了从paintComponent(Graphics g)
调用JComponent
方法的方法。
如下更改代码即可解决该问题。
public void paintComponent(Graphics g) {
super.paintComponent(g);