java swing 平滑移动_java-Swing:如何使JFrame滚动平滑?

我正在创建一个非常简单的包含可滚动文本区域的Swing GUI.但是,我在UI的响应性方面遇到一些问题.这是我用来尝试一些不同配置的类:

public class ComponentSample {

public void createWindow() {

JFrame frame = new JFrame();

frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

TextArea textArea = new TextArea(getFillerText(), 40, 120);

setViews(frame, textArea);

frame.pack();

frame.setVisible(true);

}

private void setViews(JFrame frame, TextArea textArea) {

...

}

private String getFillerText() {

String threeLines = "Why isn't scrolling smooth? \nSteve Jobs would not approve\n\n";

StringBuilder stringBuilder = new StringBuilder();

for (int i = 0; i < 100; i++) {

stringBuilder.append(threeLines);

}

return stringBuilder.toString();

}

public static void main(String[] args) throws Exception {

SwingUtilities.invokeLater(

() -> new ComponentSample().createWindow()

);

}

}

在这里,我为setViews()方法尝试了几种不同的方法体,结果如下:

在JPanel中添加textArea

JPanel panel = new JPanel();

panel.add(textArea);

frame.add(panel);

滚动1或2行,而不是按像素滚动(不平滑).快速滚动时也会闪烁白色(重绘问题?).

在视口中添加textArea

JViewport viewport = new JViewport();

viewport.setView(textArea);

frame.add(viewport);

与JPanel相同的结果.

直接添加textArea

frame.add(textArea);

与JPanel相同的结果.

在ScrollPane中添加textArea

JScrollPane scrollPane = new JScrollPane(textArea);

scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);

frame.add(scrollPane);

似乎无法正确处理滚动-它对滚轮没有响应(仅单击滚动条).滚动〜0.5行而不是像素.

同样,在以上每种情况下,用鼠标拖动滚动条时,它都会向标准输出显示以下内容(错误?IDEA以红色显示):

2016-03-17 09:45:33.413 java[40977:2845515] inOptions: {

JavaCUIThumbStartKey = 0;

"is.flipped" = 0;

kCUIOrientationKey = kCUIOrientVertical;

kCUIThumbProportionKey = "0.1328903585672379";

max = 0;

pressedpart = 0;

state = normal;

value = 0;

widget = scrollbar;

}

2016-03-17 09:45:33.413 java[40977:2845515] inOptions: {

JavaCUIThumbStartKey = 0;

"is.flipped" = 0;

kCUIOrientationKey = kCUIOrientVertical;

kCUIThumbProportionKey = "0.1328903585672379";

max = 0;

pressedpart = 0;

state = normal;

value = 0;

widget = scrollbar;

}

2016-03-17 09:45:33.414 java[40977:2845515] outHitPart = 0

如果有关系,我在OS X上.

我的问题是如何使它平滑地滚动(逐像素),而不会闪烁白色且没有打印错误?

解决方法:

不要使用作为AWT组件的TextArea.

相反,您应该使用Swing组件JTextArea.

基本代码是:

JTextArea textArea = new JTextArea(5, 20);

JScrollPane scrollPane = new JScrollPane( textArea );

frame.add( scrollPane );

编辑:

it still scrolls by full rows instead of by pixel

滚动窗格支持单位滚动和块滚动的概念. JTextArea的单位滚动是一行文本,而块滚动是视口窗口的大小.使用鼠标时,滚动(在Windows中)基于单位滚动的倍数,在我的组件上是3 *单位滚动.

如果您关心的是鼠标滚轮完成的滚动量,则可以使用Mouse Wheel Controller,它可以将乘数更改为其他值.因此,您可以将其设置为1.

如果您关注的是实际单位增量,则可以使用以下方法更改默认值:

scrollPane.getVerticalScrollBar().setUnitIncrement(1);

标签:swing,java,macos

来源: https://codeday.me/bug/20191027/1942802.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
贝塞尔曲线是一种平滑的曲线,通过控制点来定义曲线的形状。在Java中,可以通过使用Java 2D API的Path2D类来绘制和操作贝塞尔曲线。 下面是一个简单的贝塞尔曲线平滑算法的实现: ```java import java.awt.geom.Path2D; public class BezierCurve { public static Path2D smoothCurve(double[] x, double[] y) { Path2D path = new Path2D.Double(); path.moveTo(x[0], y[0]); // 为了形成闭合曲线,最后一个点需要在两个端点之间插值 double[] x0 = new double[x.length + 2]; double[] y0 = new double[y.length + 2]; System.arraycopy(x, 0, x0, 1, x.length); System.arraycopy(y, 0, y0, 1, y.length); x0[0] = x[0] * 2 - x[1]; y0[0] = y[0] * 2 - y[1]; x0[x0.length - 1] = x[x.length - 1] * 2 - x[x.length - 2]; y0[y0.length - 1] = y[y.length - 1] * 2 - y[y.length - 2]; for (int i = 1; i < x0.length - 2; i++) { double x1 = x0[i]; double y1 = y0[i]; double x2 = x0[i + 1]; double y2 = y0[i + 1]; double xc = (x1 + x2) / 2; double yc = (y1 + y2) / 2; path.quadTo(x1, y1, xc, yc); } // 为了能够在Path2D上使用close方法,需要添加一个结束点 path.lineTo(x[x.length - 1], y[y.length - 1]); path.closePath(); return path; } } ``` 这个算法使用了二次贝塞尔曲线(Path2D.quadTo)来连接所有的点。在连接相邻的点之间,算法会通过计算中点来计算控制点。为了形成闭合曲线,最后一个点需要在两个端点之间插值。最后,为了能够在Path2D上使用close方法,需要添加一个结束点。 使用这个算法可以将一组点平滑地连接成一个贝塞尔曲线: ```java import javax.swing.*; import java.awt.*; public class BezierCurveTest extends JPanel { private static final int WIDTH = 400; private static final int HEIGHT = 400; private static final double[] X = { 50, 100, 150, 200, 250, 300, 350 }; private static final double[] Y = { 200, 250, 150, 300, 100, 350, 50 }; public BezierCurveTest() { setPreferredSize(new Dimension(WIDTH, HEIGHT)); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); // 绘制原始点 g2d.setColor(Color.BLUE); for (int i = 0; i < X.length; i++) { g2d.fillOval((int) X[i] - 3, (int) Y[i] - 3, 6, 6); } // 绘制贝塞尔曲线 g2d.setColor(Color.RED); Path2D path = BezierCurve.smoothCurve(X, Y); g2d.draw(path); g2d.dispose(); } public static void main(String[] args) { JFrame frame = new JFrame("Bezier Curve Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new BezierCurveTest()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } } ``` 这个示例程序中,我们使用了一组随机生成的点来绘制贝塞尔曲线。可以看到,通过使用贝塞尔曲线平滑算法,我们可以将这些点连接成一个平滑的曲线。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值