gpt4 book ai didi

java - 为什么 JPanel 中的文本在某个点之后被剪切?

转载 作者:行者123 更新时间:2023-12-01 21:18:16 26 4
gpt4 key购买 nike

如果我们将滚动条拖过某个点,显示的文本就会变成“糊状”。我手动将字符串放在远端,看看是否可以显示并且它有效。

当我手动设置它时(如示例中所示),它从这些坐标中绘制得很好,但当我使用滚动条更改 x 坐标时,它会被剪辑)。

这是代码:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class ScrollBarDemo2 extends JFrame {
private MessagePanel messagePanel = new MessagePanel();
private JScrollBar jscbHorizontal = new JScrollBar(JScrollBar.HORIZONTAL);
private JScrollBar jscbVertical = new JScrollBar(JScrollBar.VERTICAL);
private JTextField jtfMessage = new JTextField("Example String");

public ScrollBarDemo2() {
// Add components to the frame
add(messagePanel, BorderLayout.CENTER);
add(jscbHorizontal, BorderLayout.SOUTH);
add(jscbVertical, BorderLayout.EAST);
add(jtfMessage, BorderLayout.NORTH);

// Register listener to scroll bars
ScrollBarListener jscbListener = new ScrollBarListener();
jscbHorizontal.addAdjustmentListener(jscbListener);
jscbVertical.addAdjustmentListener(jscbListener);

// Register a listener in text field
jtfMessage.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// Set the text in messagePanel to the given text
messagePanel.setText(e.getActionCommand());
}
});
}

private class ScrollBarListener implements AdjustmentListener {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
// Determine the orientation of the event source
JScrollBar scrollBar = (JScrollBar)e.getAdjustable();

if (scrollBar.getOrientation() == JScrollBar.HORIZONTAL) {
// Obtain the horizontal space remaining
double spaceAvailable = (double)messagePanel.getHorizontalEmptySpace();

// Find how much to scale each value of the scroll bars (since we're using the default 100 total values)
double scaledValue = (scrollBar.getValue() * spaceAvailable / (double)scrollBar.getMaximum());

// Set new x coordinate
messagePanel.setX((int)scaledValue);
}
else if (scrollBar.getOrientation() == JScrollBar.VERTICAL) {
// Obtain the vertical space remaining
double spaceAvailable = (double)messagePanel.getVerticalEmptySpace();

// Find how much to scale each value of the scroll bars (since we're using the default 100 total values)
double scaledValue = (scrollBar.getValue() / (double)scrollBar.getMaximum()) * spaceAvailable;

// Set new x coordinate
messagePanel.setY((int)scaledValue);
}
}
}

/** main method **/
public static void main(String[] args) {
ScrollBarDemo2 frame = new ScrollBarDemo2();
frame.setSize(500, 200);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

class MessagePanel extends JPanel {
private FontMetrics fm;
private String message = "";
private int messageX = -1;
private int messageY = -1;

public MessagePanel() {
this("Welcome to Java");
}

public MessagePanel(String message) {
this.message = message;
}

public void moveRight() {
messageX += getWidth() / 50;
repaint();
}

public void moveLeft() {
messageX -= getWidth() / 50;
repaint();
}

public void moveUp() {
messageY -= getHeight() / 100;
repaint();
}

public void moveDown() {
messageY += getHeight() / 100;
repaint();
}

public int getX() {
return messageX;
}

public int getY() {
return messageY;
}

public void setX(int x) {
messageX = x;
repaint();

}

public void setY(int y) {
messageY = y;
repaint();
}

public void setText(String newMessage) {
message = newMessage;
repaint();
}

public int getVerticalEmptySpace() {
return getHeight() - fm.getAscent();
}

public int getHorizontalEmptySpace() {
return getWidth() - fm.stringWidth(message);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);

if (messageX < 0 && messageY < 0) { // Check to initialize centered position
fm = g.getFontMetrics();

messageX = getWidth() - fm.stringWidth(message); // Manually setting it to the very end coordinate
messageY = getHeight() / 2 - fm.getAscent() / 2;
}

g.drawString(message, messageX, messageY);

}
}

最佳答案

我对您的代码做了一些更改。这是我创建的 GUI。

Scroll Bar Test

  1. 我格式化了您的代码。

  2. 我将您的 Swing 代码封装在 Runnable 中,这样我就可以在 Event Dispatch thread 上启动您的 Swing 应用程序。使用 SwingUtilities invokeLater 方法。 Oracle 和我坚持所有 Swing 应用程序都在事件调度线程上启动。

  3. 正如 camickr 在他的回答中所说,您不小心覆盖了 JPanel 的 getX、getY、setX 和 setY 方法。我重命名了你的方法。

  4. 我使用了底层 JTextField 文档的操作监听器,以便您在 JTextField 中键入的任何内容都会绘制在 JPanel 上。

您的 messageX 设置为小于零仍然存在问题。我把这个问题留给你来解决。

这是更正后的代码。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

public class ScrollBarDemo2 extends JFrame {
private static final long serialVersionUID = -3189856074534869132L;

private JScrollBar jscbHorizontal = new JScrollBar(JScrollBar.HORIZONTAL);
private JScrollBar jscbVertical = new JScrollBar(JScrollBar.VERTICAL);

private JTextField jtfMessage = new JTextField("Example String");

private MessagePanel messagePanel = new MessagePanel(jtfMessage.getText());

public ScrollBarDemo2() {
// Add components to the frame
add(messagePanel, BorderLayout.CENTER);
add(jscbHorizontal, BorderLayout.SOUTH);
add(jscbVertical, BorderLayout.EAST);
add(jtfMessage, BorderLayout.NORTH);

// Register listener to scroll bars
ScrollBarListener jscbListener = new ScrollBarListener();
jscbHorizontal.addAdjustmentListener(jscbListener);
jscbVertical.addAdjustmentListener(jscbListener);

// Register a listener in text field
jtfMessage.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
messagePanel.setText(jtfMessage.getText());
}

@Override
public void removeUpdate(DocumentEvent e) {
messagePanel.setText(jtfMessage.getText());
}

@Override
public void changedUpdate(DocumentEvent e) {
messagePanel.setText(jtfMessage.getText());
}
});

}

private class ScrollBarListener implements AdjustmentListener {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
// Determine the orientation of the event source
JScrollBar scrollBar = (JScrollBar) e.getAdjustable();

if (scrollBar.getOrientation() == JScrollBar.HORIZONTAL) {
// Obtain the horizontal space remaining
double spaceAvailable = (double) messagePanel
.getHorizontalEmptySpace();

// Find how much to scale each value of the scroll bars (since
// we're using the default 100 total values)
double scaledValue = (scrollBar.getValue() * spaceAvailable / (double) scrollBar
.getMaximum());

// Set new x coordinate
messagePanel.setMessageX((int) scaledValue);
} else if (scrollBar.getOrientation() == JScrollBar.VERTICAL) {
// Obtain the vertical space remaining
double spaceAvailable = (double) messagePanel
.getVerticalEmptySpace();

// Find how much to scale each value of the scroll bars (since
// we're using the default 100 total values)
double scaledValue = (scrollBar.getValue() / (double) scrollBar
.getMaximum()) * spaceAvailable;

// Set new x coordinate
messagePanel.setMessageY((int) scaledValue);
}
}
}

/** main method **/
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
ScrollBarDemo2 frame = new ScrollBarDemo2();
frame.setTitle("Scroll Bar Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
};
SwingUtilities.invokeLater(runnable);
}
}

class MessagePanel extends JPanel {
private static final long serialVersionUID = -2743160276473942475L;

private FontMetrics fm;
private String message = "";
private int messageX = -1;
private int messageY = -1;

public MessagePanel() {
this("Welcome to Java");
}

public MessagePanel(String message) {
this.message = message;
this.setPreferredSize(new Dimension(500, 200));
}

public void moveRight() {
messageX += getWidth() / 50;
repaint();
}

public void moveLeft() {
messageX -= getWidth() / 50;
repaint();
}

public void moveUp() {
messageY -= getHeight() / 100;
repaint();
}

public void moveDown() {
messageY += getHeight() / 100;
repaint();
}

public int getMessageX() {
return messageX;
}

public int getMessageY() {
return messageY;
}

public void setMessageX(int x) {
messageX = x;
repaint();

}

public void setMessageY(int y) {
messageY = y;
repaint();
}

public void setText(String newMessage) {
message = newMessage;
repaint();
}

public int getVerticalEmptySpace() {
return getHeight() - fm.getAscent();
}

public int getHorizontalEmptySpace() {
return getWidth() - fm.stringWidth(message);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);

if (messageX < 0 && messageY < 0) { // Check to initialize centered
// position
fm = g.getFontMetrics();

messageX = getWidth() - fm.stringWidth(message); // Manually setting
// it to the
// very end
// coordinate
messageY = getHeight() / 2 - fm.getAscent() / 2;
}

g.drawString(message, messageX, messageY);

}
}

关于java - 为什么 JPanel 中的文本在某个点之后被剪切?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39581854/

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