我認爲你的問題是一個基本的幾何。如果您嘗試將圓圈居中,則需要從其位置減去其寬度和高度的一半。就是這樣:
Ellipse2D.Float cir = new Ellipse2D.Float(
(float) (maxXValue/10 + (8 * value/1000) * (maxXValue)) - 5,
(float) (maxYValue/2) - 5, 10F, 10F);
而且你正在做的INT除法和正在返回0值,你不希望他們。更改
Line2D.Float yline = new Line2D.Float((float) maxXValue/2, (float) maxYValue * (9/20),
(float) maxXValue/2, (float) maxYValue * (11/20));
到
Line2D.Float yline = new Line2D.Float((float) maxXValue/2, (float) maxYValue * (9f/20f),
(float) maxXValue/2f, (float) maxYValue * (11f/20f));
無關的問題:
不要忘記調用父類的的paintComponent方法:
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g); // !! don't forget this!
,避免 「魔」號碼在你的p他們調試一個熊時的程式。
使用的RenderingHints理順你的Graphics2D繪圖:
// rendering hints to smooth out your drawing
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
在美國東部時間啓動Swing GUI的:
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
例如,像:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import javax.swing.JPanel;
public @SuppressWarnings("serial")
class NumberLine3 extends JPanel {
private static final double X_GAP = 1.0/20.0;
private static final double MAJOR_TIC_HT = 0.4;
private static final int PREF_W = 600;
private static final int PREF_H = 50;
private static final Stroke MAIN_STROKE = new BasicStroke(5f);
private static final Stroke MAJOR_TIC_STOKE = new BasicStroke(3f);
private static final int CIRCLE_WIDTH = 20;
private static final Color VALUE_COLOR = new Color(32, 230, 2);
private int maxX;
private int majorTickCount;
private int minorTicksPerMajor;
private double value;
public NumberLine3(int maxX, int majorTickCount, int minorTicksPerMajor, double value) {
this.maxX = maxX;
this.majorTickCount = majorTickCount;
this.minorTicksPerMajor = minorTicksPerMajor;
this.value = value;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// rendering hints to smooth out your drawing
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Graphics2D g2b = (Graphics2D) g2.create(); // so we can change stroke without problems
g2b.setStroke(MAIN_STROKE);
int x1 = (int) xValueToScreen(-maxX);
int y1 = getHeight()/2;
int x2 = (int) xValueToScreen(maxX);
int y2 = y1;
g2b.drawLine(x1, y1, x2, y2);
g2b.setStroke(MAJOR_TIC_STOKE);
for (int i = 0; i <= 2 * majorTickCount; i++) {
double xVal = ((double) i * maxX)/majorTickCount - maxX;
x1 = (int) xValueToScreen(xVal);
x2 = x1;
double dY1 = getHeight() * (1 - MAJOR_TIC_HT)/2.0;
if (i == majorTickCount) {
dY1 = 0.5 * dY1;
}
double dY2 = getHeight() - dY1;
g2b.drawLine(x1, (int) dY1, x2, (int) dY2);
}
g2b.dispose();
g2.setColor(VALUE_COLOR);
x1 = (int) (xValueToScreen(value) - CIRCLE_WIDTH/2.0);
y1 = (int) (getHeight() - CIRCLE_WIDTH)/2;
g2.fillOval(x1, y1, CIRCLE_WIDTH, CIRCLE_WIDTH);
}
private double xValueToScreen(double xValue) {
double gap = getWidth() * X_GAP;
double scale = (double) (getWidth() - 2 * gap)/(2 * maxX);
return (xValue + maxX) * scale + gap;
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value;
repaint();
}
public int getMaxX() {
return maxX;
}
public int getMajorTickCount() {
return majorTickCount;
}
public int getMinorTicksPerMajor() {
return minorTicksPerMajor;
}
}
可以測試的有:
import java.awt.BorderLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
@SuppressWarnings("serial")
public class NumberLine3Test extends JPanel {
private static final int MAX_X = 40;
private static final int MAJOR_TICS = 4;
private static final int MINOR_TICS = 5;
private double value = 0.0;
private NumberLine3 numberLine3 = new NumberLine3(MAX_X, MAJOR_TICS, MINOR_TICS, value);
private JSlider slider = new JSlider(-MAX_X, MAX_X, 0);
public NumberLine3Test() {
slider.setPaintTicks(true);
slider.setMajorTickSpacing(10);
slider.setMinorTickSpacing(5);
slider.addChangeListener(ce -> {
value = slider.getValue();
numberLine3.setValue(value);
});
JPanel sliderPanel = new JPanel();
sliderPanel.add(slider);
int ebGap = 40;
sliderPanel.setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
setLayout(new BorderLayout());
add(numberLine3, BorderLayout.PAGE_START);
add(sliderPanel);
}
private static void createAndShowGui() {
NumberLine3Test mainPanel = new NumberLine3Test();
JFrame frame = new JFrame("NumberLine3");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
請參閱編輯回答 –