gpt4 book ai didi

java - JLayer 和 JPanel 的绘画问题

转载 作者:搜寻专家 更新时间:2023-10-31 20:11:32 28 4
gpt4 key购买 nike

我想在用户输入无效时绘制一个图标。我找到了 Oracle 的示例并根据我的目的对其进行了修改。图标的绘制工作正常,但是当我更改值以更正图标时,图标不会完全不可见:在 JPanel 上绘制的部分仍然显示。

这是我的代码:

import java.awt.AlphaComposite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.text.NumberFormat;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayer;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.plaf.LayerUI;

public class FieldValidator extends JPanel {
private static final int ICON_SIZE = 12;
private static final Icon ICON = createResizedIcon((ImageIcon) UIManager.getIcon("OptionPane.errorIcon"));
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createUI();
}
});
}

public static void createUI() {
final JFrame f = new JFrame ("FieldValidator");

final JComponent content = createContent();

f.add (content);

f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo (null);
f.setVisible (true);
}

private static JComponent createContent() {
final LayerUI<JPanel> panelUI = new ValidationLayerUI();

// Number field.
final JLabel numberLabel = new JLabel("Number:");

final NumberFormat numberFormat = NumberFormat.getInstance();
final JFormattedTextField numberField = new JFormattedTextField(numberFormat) {
/**
* {@inheritDoc}
*/
@Override
public void replaceSelection(String content) {
super.replaceSelection(content);
getParent().repaint();
}
};
numberField.setColumns(16);
numberField.setFocusLostBehavior(JFormattedTextField.PERSIST);
numberField.setValue(42);

final int i = (ICON_SIZE / 2) + (ICON_SIZE % 2);
final JPanel numberPanel = new JPanel();
numberPanel.add(numberLabel);
final JPanel panel = new JPanel(new GridBagLayout());
final GridBagConstraints constr = new GridBagConstraints();
constr.insets = new Insets(i, i, i, i);
constr.weightx = 1;
constr.weighty = 1;
constr.fill = GridBagConstraints.BOTH;
panel.add(numberField, constr);
numberPanel.add(new JLayer<JPanel>(panel, panelUI));

return numberPanel;
}

//Icon resized to 12x12
private static Icon createResizedIcon(ImageIcon anIcon) {
final BufferedImage result = new BufferedImage(ICON_SIZE, ICON_SIZE, BufferedImage.TYPE_INT_ARGB);
final Graphics2D g = result.createGraphics();
g.setComposite(AlphaComposite.Src);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.drawImage(anIcon.getImage(), 0, 0, ICON_SIZE, ICON_SIZE, null);
g.dispose();
return new ImageIcon(result);

}
static class ValidationLayerUI extends LayerUI<JPanel> {

@Override
public void paint (Graphics g, JComponent c) {
super.paint (g, c);
final JLayer jlayer = (JLayer) c;
final JPanel panel = (JPanel) jlayer.getView();
final JFormattedTextField ftf = (JFormattedTextField) panel.getComponent(0);
if (!ftf.isEditValid()) {
ICON.paintIcon(panel, g, 0, panel.getHeight() - ICON.getIconHeight());
}
}

}
}

这是屏幕:初始都是正确的

enter image description here

当我绘制无效图标时,一切仍然正确

enter image description here

但是当值正确时,只有文本字段会被重绘

enter image description here

如何强制 JPanel 重绘???

附言我已经找到了一种使用 JLayeredPane 的方法,它工作正常,但我想知道我的代码有什么问题?

最佳答案

如何使用 DocumentListener:

numberField.getDocument().addDocumentListener(new DocumentListener() {
@Override public void insertUpdate(DocumentEvent e) {
//Container c = numberField.getParent();
Container c = SwingUtilities.getUnwrappedParent(numberField);
if (c != null) {
c.repaint();
}
}
@Override public void removeUpdate(DocumentEvent e) {
insertUpdate(e);
}
@Override public void changedUpdate(DocumentEvent e) {}
});

编辑

引自此链接:Painting in AWT and Swing

The RepaintManager The purpose of Swing's RepaintManager class is to maximize the efficiency of repaint processing on a Swing containment hierarchy, and also to implement Swing's 'revalidation' mechanism (the latter will be a subject for a separate article). It implements the repaint mechanism by intercepting all repaint requests on Swing components (so they are no longer processed by the AWT) and maintaining its own state on what needs to be updated (known as "dirty regions"). Finally, it uses invokeLater() to process the pending requests on the event dispatching thread, as described in the section on "Repaint Processing" (option B).

在这种情况下,当 isEditValid() 状态改变时,父级 JPanel 不是脏区。所以剩下以前的 Icon 油漆。

关于java - JLayer 和 JPanel 的绘画问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24200940/

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