/ / JLayer और JPanel के साथ पेंटिंग मुद्दा - जावा, स्विंग, jlayer

जेएलयर और जेपीनेल के साथ चित्रकारी मुद्दा - जावा, स्विंग, जेलेर

मैं एक आइकन पेंट करना चाहता हूं जब उपयोगकर्ता का इनपुट हैअवैध। मैंने ओरेकल द्वारा एक उदाहरण पाया और इसे अपने उद्देश्यों के लिए संशोधित किया। आइकन की पेंटिंग सही ढंग से काम करती है, लेकिन जब मैं आइकन को सही करने के लिए मूल्य बदलता हूं तो पूरी तरह से अदृश्य नहीं होता है: जेपीनेल के ऊपर खींचा गया हिस्सा अभी भी प्रदर्शित होता है।

मेरा कोड यहाँ है:

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());
}
}

}
}

यहाँ स्क्रीन है: शुरू में सब सही है

यहां छवि विवरण दर्ज करें

जब मैं अमान्य चिह्न पेंट करता हूं, तब भी सब सही होता है

यहां छवि विवरण दर्ज करें

लेकिन जब मूल्य सही हो जाता है तो केवल पाठ फ़ील्ड को फिर से लिखा जाएगा

यहां छवि विवरण दर्ज करें

मैं जेपीएनएल को फिर से कैसे मजबूर कर सकता हूं ???

अनुलेख मुझे पहले से ही JLayeredPane के साथ एक दृष्टिकोण मिल गया है जो सही काम करता है, लेकिन मैं जानना चाहता हूं कि मेरे कोड में क्या गलत है?

उत्तर:

उत्तर № 1 के लिए 4

कैसे का उपयोग करने के बारे में 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) {}
});

संपादित करें

इस लिंक से उद्धरण: एडब्ल्यूटी और स्विंग में चित्रकारी

RepaintManager स्विंग का उद्देश्य RepaintManager वर्ग के लिए है अधिकतम दक्षता एक स्विंग पर दमनकारी प्रसंस्करण कीरोकथाम पदानुक्रम, और यह भी लागू करने के लिए झूले "अमान्य" तंत्र (ए उत्तरार्द्ध एक अलग लेख के लिए एक विषय होगा)। इसे लागू करता है दमन के सभी अनुरोधों को रोककर दमन तंत्र घटक (ताकि वे अब AWT द्वारा संसाधित न हों) और अद्यतन किए जाने की आवश्यकता पर अपना स्वयं का राज्य बनाए रखना (गंदे के रूप में जाना जाता है) क्षेत्रों ")। अंत में, यह लंबित प्रक्रिया को लागू करने के लिए invokeLater () का उपयोग करता है अनुभाग में वर्णित के रूप में घटना प्रेषण धागे पर अनुरोध "रिप्रेंट प्रोसेसिंग" (विकल्प बी) पर।

इस मामले में जनक JPanel गंदा क्षेत्र नहीं है isEditValid() स्थिति बदल गई। इतना शेष पिछले Icon रंग।