2010-04-01 20 views
9

पर घटक रखना मेरे पास जेएलएबल का उप-वर्ग है जो मेरे जीयूआई का एक घटक बनाता है। मैंने घटक को एक कंटेनर से दूसरे में खींचने और छोड़ने की क्षमता लागू की है, लेकिन बिना किसी दृश्य प्रभाव के। मैं इस जेएलएबल को एक कंटेनर से दूसरे में आइटम के ड्रैग के दौरान कर्सर का पालन करना चाहता हूं। मैंने सोचा कि मैं सिर्फ एक ग्लास फलक बना सकता हूं और इसे वहां खींच सकता हूं। हालांकि, मैं ग्लास फलक में घटक जोड़ने के बाद भी, घटक को दृश्यमान सेट करता हूं, और ग्लास फलक दृश्यमान सेट करता हूं, और ग्लास फलक को अपारदर्शी के रूप में सेट करता हूं, फिर भी मुझे घटक दिखाई नहीं देता है। मुझे घटक काम पता है क्योंकि मैं इसे सामग्री फलक में जोड़ सकता हूं और इसे दिखा सकता हूं।ग्लास फलक

मैं ग्लास फलक में एक घटक कैसे जोड़ूं?


अंत में यह पता चला कि सरल उदाहरण कैसे काम करना है। धन्यवाद, @ कफ। मैं इस समाधान को अपनी मूल समस्या में अनुकूलित करने में सक्षम था, जिससे मुझे जावा 2 डी कोड की ~ 60 लाइनों को हटा दिया गया जो मैन्युअल रूप से जेएलएबल का प्रतिनिधित्व प्रस्तुत करता था।

package test; 

import java.awt.Color; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.border.LineBorder; 

public class MainFrame extends JFrame { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     MainFrame mf = new MainFrame(); 
     mf.setSize(400, 400); 
     mf.setLocationRelativeTo(null); 
     mf.setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
     mf.setGlassPane(new JPanel()); 

     JLabel l = new JLabel(); 
     l.setText("Hello"); 
     l.setBorder(new LineBorder(Color.BLACK, 1)); 
     l.setBounds(10, 10, 50, 20); 
     l.setBackground(Color.RED); 
     l.setOpaque(true); 
     l.setPreferredSize(l.getSize()); 

     //mf.add(l); 
     ((JPanel)mf.getGlassPane()).add(l); 
     mf.getGlassPane().setVisible(true); 

     mf.setVisible(true); 
    } 
} 
+0

आप glasspane करने के लिए इसे जोड़ने के बजाय glasspane के रूप में अपने घटक स्थापित करने की कोशिश की है? – willcodejavaforfood

+0

यह घटक एक शब्द गेम में एक टाइल का प्रतिनिधित्व करता है, इसलिए यह केवल 37 * 37 है और प्रभाव के लिए सीमाओं का उपयोग करता है। मैं नहीं देखता कि मैं इसे एक ग्लास फलक में कैसे बदल सकता हूं क्योंकि यह टाइल के आयामों के साथ गड़बड़ कर देगा। –

+0

क्या हम कुछ कोड देख सकते हैं? विशेष रूप से आप ग्लास फलक में घटक कैसे जोड़ते हैं और इसे दृश्यमान सेट करते हैं। –

उत्तर

3

LayerPane उदाहरण की ओर इशारा इसके अलावा पहले से ही अपने लेबल के पसंदीदा आकार की स्थापना के चारों ओर अपने मूल कोड केन्द्रों के साथ प्रदान की है, मुद्दा। JLabel के आकार के पहले आप इसे सेट करते हैं, इसलिए आपका:

l.setPreferredSize(l.getSize()); 

अप्रभावी है। यदि, दूसरी तरफ, आप setBounds पर अपनी कॉल करने के बाद उस कॉल को बनाते हैं, तो आप अपने वांछित परिणाम देखेंगे।

l.setPreferredSize(l.getSize()); 
l.setBounds(10, 10, 50, 20); 

इस तरह देखने के लिए: इसे ध्यान में रखते, इस को पुन: व्यवस्थित

l.setBounds(10, 10, 50, 20); 
l.setPreferredSize(l.getSize()); 
13

नीचे दिया गया उदाहरण कोड दिखाता है कि शतरंज बोर्ड के चारों ओर एक शतरंज के टुकड़े को कैसे खींचें। यह ग्लास फलक के बजाय जेलेयरपेन का उपयोग करता है, लेकिन मुझे यकीन है कि अवधारणाएं वही होंगी। यही कारण है:

क) जड़ फलक
ख) के लिए कांच फलक जोड़ने गिलास फलक दिखाई
ग) यकीन है कि सीमा से मान्य होते हैं
घ बनाने कांच फलक पर घटक जोड़ने) का उपयोग setLocation बनाने () घटक

संपादित की खींचने चेतन करने के लिए: जोड़ा कोड लेआउट प्रबंधकों का उपयोग जब आप setSize() या setBounds() तरीकों का उपयोग कभी नहीं SSCCE

JLabel l = new JLabel(); 
l.setText("Hello"); 
l.setBorder(new LineBorder(Color.BLACK, 1)); 
// l.setPreferredSize(l.getSize()); 
// l.setBounds(10, 10, 50, 20); 
((JPanel)mf.getGlassPane()).add(l); 

mf.setVisible(true); 
mf.getGlassPane().setVisible(true); 

ठीक करने के लिए। आपके मामले में आप केवल पसंदीदा आकार (0, 0) पर सेट करते हैं क्योंकि यह सभी घटकों का डिफ़ॉल्ट आकार है।

यह तब काम करता है जब आप फ्रेम में लेबल जोड़ते हैं क्योंकि फ्रेम के सामग्री फलक के लिए डिफ़ॉल्ट लेआउट प्रबंधक एक सीमा लेआउट है, इसलिए लेबल के पसंदीदा आकार को अनदेखा किया जाता है और लेबल को फ्रेम का आकार बनाया जाता है ।

हालांकि, डिफ़ॉल्ट रूप से एक जेपीनल फ़्लोलाउट का उपयोग करता है जो घटक के पसंदीदा आकार का सम्मान करता है। चूंकि पसंदीदा आकार 0 है, इसलिए पेंट करने के लिए कुछ भी नहीं है।

इसके अलावा, ग्लास फलक को चित्रित करने के लिए दृश्यमान बनाने की आवश्यकता है।

मेरा सुझाव है कि आप Swing tutorial पढ़ लें। लेआउट प्रबंधक कैसे काम करते हैं और ग्लास पैन कैसे काम करते हैं और प्रत्येक अनुभाग में काम करने वाले उदाहरण हैं इस पर अनुभाग हैं।

संपादित करें: उदाहरण कोड के नीचे कहा:

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

public class ChessBoard extends JFrame implements MouseListener, MouseMotionListener 
{ 
    JLayeredPane layeredPane; 
    JPanel chessBoard; 
    JLabel chessPiece; 
    int xAdjustment; 
    int yAdjustment; 

    public ChessBoard() 
    { 
     Dimension boardSize = new Dimension(600, 600); 

     // Use a Layered Pane for this this application 

     layeredPane = new JLayeredPane(); 
     layeredPane.setPreferredSize(boardSize); 
     layeredPane.addMouseListener(this); 
     layeredPane.addMouseMotionListener(this); 
     getContentPane().add(layeredPane); 

     // Add a chess board to the Layered Pane 

     chessBoard = new JPanel(); 
     chessBoard.setLayout(new GridLayout(8, 8)); 
     chessBoard.setPreferredSize(boardSize); 
     chessBoard.setBounds(0, 0, boardSize.width, boardSize.height); 
     layeredPane.add(chessBoard, JLayeredPane.DEFAULT_LAYER); 

     // Build the Chess Board squares 

     for (int i = 0; i < 8; i++) 
     { 
      for (int j = 0; j < 8; j++) 
      { 
       JPanel square = new JPanel(new BorderLayout()); 
       square.setBackground((i + j) % 2 == 0 ? Color.red : Color.white); 
       chessBoard.add(square); 
      } 
     } 

     // Add a few pieces to the board 

     ImageIcon duke = new ImageIcon("dukewavered.gif"); // add an image here 

     JLabel piece = new JLabel(duke); 
     JPanel panel = (JPanel)chessBoard.getComponent(0); 
     panel.add(piece); 
     piece = new JLabel(duke); 
     panel = (JPanel)chessBoard.getComponent(15); 
     panel.add(piece); 
    } 

    /* 
    ** Add the selected chess piece to the dragging layer so it can be moved 
    */ 
    public void mousePressed(MouseEvent e) 
    { 
     chessPiece = null; 
     Component c = chessBoard.findComponentAt(e.getX(), e.getY()); 

     if (c instanceof JPanel) return; 

     Point parentLocation = c.getParent().getLocation(); 
     xAdjustment = parentLocation.x - e.getX(); 
     yAdjustment = parentLocation.y - e.getY(); 
     chessPiece = (JLabel)c; 
     chessPiece.setLocation(e.getX() + xAdjustment, e.getY() + yAdjustment); 

     layeredPane.add(chessPiece, JLayeredPane.DRAG_LAYER); 
     layeredPane.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); 
    } 

    /* 
    ** Move the chess piece around 
    */ 
    public void mouseDragged(MouseEvent me) 
    { 
     if (chessPiece == null) return; 

     // The drag location should be within the bounds of the chess board 

     int x = me.getX() + xAdjustment; 
     int xMax = layeredPane.getWidth() - chessPiece.getWidth(); 
     x = Math.min(x, xMax); 
     x = Math.max(x, 0); 

     int y = me.getY() + yAdjustment; 
     int yMax = layeredPane.getHeight() - chessPiece.getHeight(); 
     y = Math.min(y, yMax); 
     y = Math.max(y, 0); 

     chessPiece.setLocation(x, y); 
    } 

    /* 
    ** Drop the chess piece back onto the chess board 
    */ 
    public void mouseReleased(MouseEvent e) 
    { 
     layeredPane.setCursor(null); 

     if (chessPiece == null) return; 

     // Make sure the chess piece is no longer painted on the layered pane 

     chessPiece.setVisible(false); 
     layeredPane.remove(chessPiece); 
     chessPiece.setVisible(true); 

     // The drop location should be within the bounds of the chess board 

     int xMax = layeredPane.getWidth() - chessPiece.getWidth(); 
     int x = Math.min(e.getX(), xMax); 
     x = Math.max(x, 0); 

     int yMax = layeredPane.getHeight() - chessPiece.getHeight(); 
     int y = Math.min(e.getY(), yMax); 
     y = Math.max(y, 0); 

     Component c = chessBoard.findComponentAt(x, y); 

     if (c instanceof JLabel) 
     { 
      Container parent = c.getParent(); 
      parent.remove(0); 
      parent.add(chessPiece); 
      parent.validate(); 
     } 
     else 
     { 
      Container parent = (Container)c; 
      parent.add(chessPiece); 
      parent.validate(); 
     } 
    } 

    public void mouseClicked(MouseEvent e) {} 
    public void mouseMoved(MouseEvent e) {} 
    public void mouseEntered(MouseEvent e) {} 
    public void mouseExited(MouseEvent e) {} 

    public static void main(String[] args) 
    { 
     JFrame frame = new ChessBoard(); 
     frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
     frame.setResizable(false); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 
+0

मुझे जेएलएर्डपेन को स्विच करने में थोड़ी सी परेशानी हो रही है क्योंकि मैं अपने मुख्य रूप के लेआउट के लिए ग्रिडबैगआउट का उपयोग करता हूं। यह DRAG_LAYER के साथ गड़बड़ है क्योंकि इसमें शेष सामग्री प्रबंधक के रूप में एक ही लेआउट प्रबंधक होना आवश्यक है, लेकिन मुझे लेआउट मैनेजर नहीं चाहिए क्योंकि यह केवल ड्रैगिंग के लिए उपयोग किया जा रहा है। –

+0

मेरा उदाहरण ग्रिडलाउट का उपयोग करता है और DRAG_LAYER को उसी लेआउट प्रबंधक का उपयोग करने की आवश्यकता नहीं है। वास्तव में यह लेआउट प्रबंधकों का उपयोग नहीं करता है क्योंकि आप मैन्युअल रूप से घटकों को पोजिशन कर रहे हैं। मैं सुझाव नहीं दे रहा हूं कि आपको तैरने की आवश्यकता है और केवल एक स्तरित फलक का उपयोग करें कि अवधारणाएं समान हों। ऐसा इसलिए है क्योंकि एक गिलास फलक भी एक लेआउट मैनेजर का उपयोग नहीं करता है जिसे आप घटक की सीमाओं को सही तरीके से सेट करने के लिए जिम्मेदार हैं। वैसे भी मैं भविष्य में मदद नहीं कर सकता। मैंने आपको कामकाजी कोड दिया, मुझे नहीं पता कि आपका कोड अलग कैसे है। – camickr

+3

एक साधारण एसएससीसीई (http://sscce.org) बनाकर शुरू करें जो किसी विशेष स्थिति पर जेएलएबल के साथ ग्लास फलक प्रदर्शित करता है। एक बार जब आप इसे मास्टर कर लेंगे, तो आप लेबल के स्थान को एनिमेट करने के लिए आगे बढ़ते हैं जब आप इसे माउस से खींचते हैं। यदि आप एसएससीसीई काम नहीं कर पा रहे हैं तो आपके पास पोस्ट करने के लिए सरल कोड है और हम अधिक ठोस सुझाव प्रदान कर सकते हैं। – camickr

3

के बाद से मैं एक लंबे समय के लिए स्विंग पर रोमेन लड़का के ब्लॉग का अनुसरण किया गया था। मेरे पास एक लिंक है जिसमें आपको रुचि हो सकती है। उसने स्रोत जारी किया - जिसने डीएनडी प्रभावों के लिए ग्लासपेन का उपयोग किया।

http://jroller.com/gfx/entry/drag_and_drop_effects_the

मैं अपने आप को कभी नहीं एक fizzy एनीमेशन/DnD पर प्रभाव का उपयोग किया था, इसलिए किसी भी आगे की टिप्पणी नहीं कर सकता: - |

+0

दुर्भाग्य से, स्विंग द्वारा प्रदान किए गए घटकों की बजाय सीधे ग्लास फलक पर खींची गई छवियों का उपयोग करता है। –

+0

इससे कोई फर्क नहीं पड़ता कि उदाहरण छवियों को खींचता है। घटकों का उपयोग करने के लिए, आप केवल ग्लास फलक में घटक जोड़ते हैं और सुनिश्चित करते हैं कि आपने सीमाएं ठीक से सेट की हैं। – camickr

+0

समस्या यह थी कि मैं ग्लास फलक में घटक जोड़ रहा हूं और इसकी सीमा निर्धारित कर रहा हूं, लेकिन यह अभी भी प्रदर्शित नहीं हो रहा था। एकमात्र चीज जो मैं समझ सकता हूं वह यह है कि मुझे नहीं पता कि किसी घटक पर सीमाओं को सही तरीके से कैसे सेट किया जाए। –

11

हालांकि सवाल का स्पर्शरेखा, JLayeredPaneexample @camickr द्वारा उद्धृत निम्नलिखित अनुकूलन है, जो एक मौजूदा घटक से अधिक mouseReleased() के प्रभाव पर प्रकाश डाला गया मानते हैं।

public ChessBoard() { 
    ... 
    // Add a few pieces to the board 
    addPiece(3, 0, "♛"); 
    addPiece(4, 0, "♚"); 
    addPiece(3, 7, "♕"); 
    addPiece(4, 7, "♔"); 
} 

static Font font = new Font("Sans", Font.PLAIN, 72); 

private void addPiece(int col, int row, String glyph) { 
    JLabel piece = new JLabel(glyph, JLabel.CENTER); 
    piece.setFont(font); 
    JPanel panel = (JPanel) chessBoard.getComponent(col + row * 8); 
    panel.add(piece); 
} 
+0

@ डेविड क्राउकंप: ग्लिफ को अनुकूलित करने पर अधिक [यहां] (http://stackoverflow.com/q/18686199/230513)। – trashgod

संबंधित मुद्दे