मैं साझा करने के लिए स्क्रीन के क्षेत्र का चयन करने के उद्देश्य से JWindow
पर आधारित कस्टम UI बनाने का प्रयास कर रहा हूं। मैंने JWindow
बढ़ाया है और AWTUtilities.setWindowShape()
का उपयोग कर विंडो के केंद्र को 'आकार देने' के लिए कोड जोड़ा है।स्विंग जेविंडो को झटके के बिना कैसे बदला जा सकता है?
कोड चलाते समय मुझे झिलमिलाहट का सामना करना पड़ रहा है क्योंकि विंडो को नकारात्मक एक्स और वाई दिशाओं में बदल दिया गया है, यानी ऊपर और बाएं। ऐसा प्रतीत होता है कि घटकों को अद्यतन करने से पहले खिड़की का आकार बदलकर खींचा जाता है। नीचे कोड का एक सरलीकृत संस्करण है। जब ऊपर पैनल चलाया जाता है तो विंडो को ऊपर और बाईं ओर आकार देने के लिए उपयोग किया जा सकता है। खिड़की की पृष्ठभूमि को यह स्पष्ट करने के लिए हरे रंग पर सेट किया गया है कि पिक्सेल जो मैं दिखाना नहीं चाहता हूं।
संपादित करें: विंडो ठीक से एक ComponentListener
का उपयोग कर आकार देने के लिए कोड में सुधार और आगे झिलमिलाहट (भी अद्यतन स्क्रीनशॉट) को वर्णन करने के तल पर एक डमी घटक जोड़ा।
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Area;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.border.LineBorder;
import com.sun.awt.AWTUtilities;
public class FlickerWindow extends JWindow implements MouseListener, MouseMotionListener{
JPanel controlPanel;
JPanel outlinePanel;
int mouseX, mouseY;
Rectangle windowRect;
Rectangle cutoutRect;
Area windowArea;
public static void main(String[] args) {
FlickerWindow fw = new FlickerWindow();
}
public FlickerWindow() {
super();
setLayout(new BorderLayout());
setBounds(500, 500, 200, 200);
setBackground(Color.GREEN);
controlPanel = new JPanel();
controlPanel.setBackground(Color.GRAY);
controlPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
controlPanel.addMouseListener(this);
controlPanel.addMouseMotionListener(this);
outlinePanel = new JPanel();
outlinePanel.setBackground(Color.BLUE);
outlinePanel.setBorder(new CompoundBorder(new EmptyBorder(2,2,2,2), new LineBorder(Color.RED, 1)));
add(outlinePanel, BorderLayout.CENTER);
add(controlPanel, BorderLayout.NORTH);
add(new JButton("Dummy button"), BorderLayout.SOUTH);
setVisible(true);
setShape();
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
setShape();
}});
}
public void paint(Graphics g) {
// un-comment or breakpoint here to see window updates more clearly
//try {Thread.sleep(10);} catch (Exception e) {}
super.paint(g);
}
public void setShape() {
Rectangle bounds = getBounds();
Rectangle outlineBounds = outlinePanel.getBounds();
Area newShape = new Area (new Rectangle(0, 0, bounds.width, bounds.height));
newShape.subtract(new Area(new Rectangle(3, outlineBounds.y + 3, outlineBounds.width - 6, outlineBounds.height - 6)));
setSize(bounds.width, bounds.height);
AWTUtilities.setWindowShape(this, newShape);
}
public void mouseDragged(MouseEvent e) {
int dx = e.getXOnScreen() - mouseX;
int dy = e.getYOnScreen() - mouseY;
Rectangle newBounds = getBounds();
newBounds.translate(dx, dy);
newBounds.width -= dx;
newBounds.height -= dy;
mouseX = e.getXOnScreen();
mouseY = e.getYOnScreen();
setBounds(newBounds);
}
public void mousePressed(MouseEvent e) {
mouseX = e.getXOnScreen();
mouseY = e.getYOnScreen();
}
public void mouseMoved(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
अधिरोहित paint()
विधि या एक ब्रेकपाइंट के रूप में इस्तेमाल किया जा सकता Thread.sleep()
वहाँ uncommented अद्यतन का स्पष्ट स्थिति प्रदान करने के लिए के रूप में यह होता है हो सकता है।
मेरी समस्या setBounds()
विधि से स्टेम लगती है जिससे खिड़की को स्क्रीन पर चित्रित करने से पहले चित्रित किया जा सकता है।
विंडो बड़ा आकार बदलने (अप और बाएं) के रूप में) ओवरराइड paint()
विधि पर ब्रेकप्वाइंट पर देखा दौरान:
विंडो का आकार बदलने, के रूप में यह देखना चाहिए से पहले
छोटे आकार बदलने (नीचे और दाएं) के रूप में ओवरराइडpaint()
विधि पर ब्रेकप्वाइंट पर देखा दौरान
विंडो):
दी इन स्क्रीनशॉट आक्रामक माउस खींचें आंदोलनों के दौरान लिया जाता है, लेकिन झिलमिलाहट काफी हो जाता है अधिक मध्यम माउस ड्रैग के लिए भी परेशान।
बड़े स्क्रीनशॉट के आकार में हरा क्षेत्र नई पृष्ठभूमि दिखाता है जो किसी भी चित्रकला/लेआउट से पहले खींचा जाता है, ऐसा लगता है कि अंतर्निहित ComponentPeer
या मूल विंडो प्रबंधक में ऐसा लगता है। 'छोटे आकार में' स्क्रीनशॉट पर नीला क्षेत्र JPanel
की पृष्ठभूमि को धक्का में दिखाया जा रहा है लेकिन अब पुराना है। यह लिनक्स (उबंटू) और विंडोज एक्सपी के तहत होता है।
क्या किसी को स्क्रीन पर किए गए किसी भी बदलाव से पहले बैक बफर का आकार बदलने के लिए Window
या JWindow
का कारण बनने का कोई तरीका मिला है और इस प्रकार इस झटकेदार प्रभाव से बचें? शायद java.awt....
सिस्टम प्रॉपर्टी है जिसे इस से बचने के लिए सेट किया जा सकता है, हालांकि मुझे कोई नहीं मिला।
# 2 संपादित करें: टिप्पणी बाहर AWTUtilities.setWindowShape()
करने के लिए कॉल (और वैकल्पिक paint()
में Thread.sleep(10)
लाइन uncomment) तो क्रम में आक्रामक तरीके से चारों ओर शीर्ष पैनल खींचें स्पष्ट रूप से झिलमिलाहट की प्रकृति को देखने के लिए।
संपादित करें # 3: क्या कोई भी विंडोज 7 या मैक ओएसएक्स पर सन जावा के तहत इस व्यवहार का परीक्षण करने में सक्षम है?
@ विल्जक्रोज़: +1, बहुत अच्छी तरह से तैयार प्रश्न। और सभी के लिए: कृपया ** ** ** बिना किसी उत्तर के उत्तर दें ** ALSO ** प्रश्न को ऊपर उठाना। – SyntaxT3rr0r
मैं एक ही प्रश्न का उत्तर जानना चाहता हूं - मैंने इसे वर्षों से नफरत की है, लेकिन कभी भी एक हैकी कामकाज नहीं मिला। विंडोज 7 पर परीक्षण किया गया और हालांकि मुझे काफी प्रभाव नहीं मिलते हैं क्योंकि मुझे कुछ बहुत समान मिलता है। प्रत्येक जावा एप्लिकेशन के लिए कलाकृतियों का आकार बदलना, न केवल आपके उदाहरण के लिए देखा जाता है। उत्सुकता से, एक खिड़की को ठीक से काम करना ठीक है, केवल आकार बदलना बेकार है (संभवतया क्योंकि विंडोज 7 विंडोज़ को ही चलाता है और जावा में आकार बदलता नहीं है - अगर मैं सही ढंग से याद करता हूं तो विंडोज एक्सपी के विपरीत)। – Domchi
@ डोम्ची: विंडोज 7 :-) पर होने की पुष्टि के लिए धन्यवाद। XP पर विंडो को स्थानांतरित करना कोई पश्चाताप के साथ चिकनी लगता है। हो सकता है कि आप XP पर खराब होने पर विंडो 'मरम्मत' का जिक्र कर रहे हों। कंपोजिटिंग डब्लूएम (जैसा कि विस्टा/विन 7, ओएसएक्स और कंपिज़ इत्यादि में लिनक्स पर देखा गया है) पश्चाताप के अनुरोध किए बिना विंडोज के पूर्व अस्पष्ट हिस्सों की 'मरम्मत' को संभालता है, यह वह जगह है जहां मुझे लगता है कि एक्सपी गिर सकता है। – willjcroz