gpt4 book ai didi

java - 重新绘制 Swing 组件会产生糟糕的结果

转载 作者:行者123 更新时间:2023-12-01 11:47:31 25 4
gpt4 key购买 nike

我“画”了一个组件来制作一种旋钮,因为我没有找到一种拥有“圆形 JSlider”的方法。我使用抗锯齿来获得良好的结果。当我用鼠标按下组件时,我修改光标位置并要求组件重新绘制。然后,问题出现了:重新绘制的结果很糟糕!

如果我要求仅在释放鼠标时重新绘制,结果似乎保持正确。但是,如果我在设置旋钮时不“连续”重新绘制组件,那么设置旋钮值会更复杂。

导致问题的“repaint”方法位于类末尾的 run 方法中。

有人已经遇到这个问题了吗?可以用什么样的方案来解决呢?这是我正在使用的代码:

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

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 angleCursorOrigin;
double angleCursorInitial;
Color backgroundColor, knobColor;
boolean mousePressed;
Thread t;

Knob () {
System.out.println("Knob");
angleCursorOrigin=0.5;
angleCursorInitial=0.5;
knobColor =new Color(0,255,0,255);
minorTick=9;
majorTick=3;

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.6);
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-angleCursorOrigin*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));

}

@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) {
angleCursorOrigin=angleCursorInitial;
repaint();
}
}

@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;
angleCursorOrigin=angleCursorOrigin+yDeltaMouse;
yMouseOrigin=yMouse;
if (angleCursorOrigin >=1) {
angleCursorOrigin=1;
} else if (angleCursorOrigin <= 0) {
angleCursorOrigin=0;
}
//This repaint is a problem if I "uncomment" it
//repaint();
}

}

}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame frame = new JFrame();
frame.setSize(300,90);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new Knob());
frame.setVisible(true);

}

}

最佳答案

首先,在 paintComponent 方法中执行自定义绘制之前,您不会调用 super.paintComponent

参见Painting in AWT and SwingPerforming Custom Painting了解更多详情

然后转向这样一个事实:您的“鼠标跟踪线程”太过分了,实际上并不是必需的。相反,您应该使用 MouseMotionListener,请参阅 How to Write a Mouse Listener了解更多详情。

这将使您无需在本地和屏幕上下文之间进行转换。

关于java - 重新绘制 Swing 组件会产生糟糕的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29043245/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com