2013-03-14 5 views
6

पर क्लिक करके खींचें और माउस खींचें जब मैं स्विंग कक्षाओं का उपयोग करके ग्रिड UI (5 * 5) बनाने की कोशिश कर रहा हूं। मैंने एक नेस्टेड लूप की कोशिश की और जेएफआरएएम को गतिशील रूप से एक जेपीनल जोड़ दिया। और जब भी उपयोगकर्ता क्लिक करता है और उस पर गिरता है तो मैंने प्रत्येक जेपीनल के पृष्ठभूमि रंग को बदलने की भी कोशिश की। लेकिन मेरे कोड के साथ प्रत्येक सेल के बीच भारी अंतर हैं और मैं ड्रैग इवेंट को काम नहीं कर सकता।स्विंग क्लास जावा का उपयोग करके ग्रिड कैसे आकर्षित करें और

public class clsCanvasPanel extends JPanel { 
    private static final int intRows = 5; 
    private static final int intCols = 5; 
    private List<JPanel> jpllist = new ArrayList<JPanel>(); 

    public clsCanvasPanel() {       
     /* 
     * 
     * Add eventListener to individual JPanel within CanvasPanel 
     * 
     * 
     * TODO : 
     * 1) mousePressed --> update Temperature and HeatConstant of clsElement Class 
     * 2) start a new thread and 
     * 3) call clsElement.run() method 
     * 
     * 
     * Right Now : it updates the colours of the JPanel 
     * */ 
      MouseListener mouseListener = new MouseAdapter() { 
      @Override 
      public void mousePressed(MouseEvent e) { 
       JPanel panel = (JPanel) e.getSource(); 

       Component[] components = panel.getComponents(); 
       for (Component component : components) { 
        component.setVisible(!component.isVisible()); 
        component.setBackground(new Color(255,255,0)); 
       } 
       panel.revalidate(); 
       panel.repaint(); 
      } 
      }; 

      //TODO : refactoring 
      GridLayout gdlyPlates = new GridLayout(); 
      gdlyPlates.setColumns(intCols); 
      gdlyPlates.setRows(intRows); 
      gdlyPlates.setHgap(0); 
      gdlyPlates.setVgap(0); 
      setLayout(gdlyPlates); 

      //TODO : refactoring 
      for (int row = 0; row < intRows; row++) { 
       for (int col = 0; col < intCols; col++) { 
       JPanel panel = new JPanel(new GridBagLayout()); 
       panel.setOpaque(false); 
       JPanel jl = new JPanel(); 
       jl.setVisible(true); 
       panel.add(jl); 
       panel.addMouseListener(mouseListener); 
       jpllist.add(panel); 
       add(panel); 
       } 
      } 
    } 
} 

तो अब मैं आगे प्रत्येक कोशिका का रंग बदलने के एक पैनल बना सकते हैं और उस पर ग्रिड आकर्षित करने के लिए कोशिश कर रहा हूँ, तो ग्रिड पर माउस स्थिति का पता लगाता है,।

क्या कोई मुझे जेपीनेल पर इस ग्रिड को कार्यान्वित करने और किसी चुने हुए सेल के रंग को बदलने के बारे में कुछ सलाह दे सकता है।

उत्तर

31

काम करने के लिए इसे पाने के कई तरीके हैं, जो आप प्राप्त करना चाहते हैं उसके आधार पर।

यह पहला उदाहरण कोशिकाओं को हाइलाइट करने के लिए कोशिकाओं को प्रस्तुत करने के लिए 2 डी ग्राफिक्स एपीआई और MouseMotionListener का उपयोग करता है।

enter image description here

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TestGrid01 { 

    public static void main(String[] args) { 
     new TestGrid01(); 
    } 

    public TestGrid01() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private int columnCount = 5; 
     private int rowCount = 5; 
     private List<Rectangle> cells; 
     private Point selectedCell; 

     public TestPane() { 
      cells = new ArrayList<>(columnCount * rowCount); 
      MouseAdapter mouseHandler; 
      mouseHandler = new MouseAdapter() { 
       @Override 
       public void mouseMoved(MouseEvent e) { 
        Point point = e.getPoint(); 

        int width = getWidth(); 
        int height = getHeight(); 

        int cellWidth = width/columnCount; 
        int cellHeight = height/rowCount; 

        selectedCell = null; 
        if (e.getX() >= xOffset && e.getY() >= yOffset) { 

         int column = (e.getX() - xOffset)/cellWidth; 
         int row = (e.getY() - yOffset)/cellHeight; 

         if (column >= 0 && row >= 0 && column < columnCount && row < rowCount) { 

          selectedCell = new Point(column, row); 

         } 

        } 
        repaint(); 

       } 
      }; 
      addMouseMotionListener(mouseHandler); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     public void invalidate() { 
      cells.clear(); 
      selectedCell = null; 
      super.invalidate(); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 

      int width = getWidth(); 
      int height = getHeight(); 

      int cellWidth = width/columnCount; 
      int cellHeight = height/rowCount; 

      int xOffset = (width - (columnCount * cellWidth))/2; 
      int yOffset = (height - (rowCount * cellHeight))/2; 

      if (cells.isEmpty()) { 
       for (int row = 0; row < rowCount; row++) { 
        for (int col = 0; col < columnCount; col++) { 
         Rectangle cell = new Rectangle(
           xOffset + (col * cellWidth), 
           yOffset + (row * cellHeight), 
           cellWidth, 
           cellHeight); 
         cells.add(cell); 
        } 
       } 
      } 

      if (selectedCell != null) { 

       int index = selectedCell.x + (selectedCell.y * columnCount); 
       Rectangle cell = cells.get(index); 
       g2d.setColor(Color.BLUE); 
       g2d.fill(cell); 

      } 

      g2d.setColor(Color.GRAY); 
      for (Rectangle cell : cells) { 
       g2d.draw(cell); 
      } 

      g2d.dispose(); 
     } 
    } 
} 

यह उदाहरण खिड़की के साथ ग्रिड का आकार परिवर्तन करता है, लेकिन यह कोशिकाओं तय आकार बनाने के लिए एक छोटी सी परिवर्तन होगा। घटक उदाहरण

इस उदाहरण के साथ

चेक बाहर 2D Graphics अधिक जानकारी के लिए

अद्यतन JPanel रों की एक श्रृंखला का उपयोग करता है प्रत्येक कोशिका प्रतिनिधित्व करते हैं।

प्रत्येक सेल को निश्चित चौड़ाई और ऊंचाई के साथ परिभाषित किया जाता है और मुख्य विंडो के साथ आकार बदलता नहीं है।

enter image description here

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

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.border.Border; 
import javax.swing.border.MatteBorder; 

public class TestGrid02 { 

    public static void main(String[] args) { 
     new TestGrid02(); 
    } 

    public TestGrid02() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
      setLayout(new GridBagLayout()); 

      GridBagConstraints gbc = new GridBagConstraints(); 
      for (int row = 0; row < 5; row++) { 
       for (int col = 0; col < 5; col++) { 
        gbc.gridx = col; 
        gbc.gridy = row; 

        CellPane cellPane = new CellPane(); 
        Border border = null; 
        if (row < 4) { 
         if (col < 4) { 
          border = new MatteBorder(1, 1, 0, 0, Color.GRAY); 
         } else { 
          border = new MatteBorder(1, 1, 0, 1, Color.GRAY); 
         } 
        } else { 
         if (col < 4) { 
          border = new MatteBorder(1, 1, 1, 0, Color.GRAY); 
         } else { 
          border = new MatteBorder(1, 1, 1, 1, Color.GRAY); 
         } 
        } 
        cellPane.setBorder(border); 
        add(cellPane, gbc); 
       } 
      } 
     } 
    } 

    public class CellPane extends JPanel { 

     private Color defaultBackground; 

     public CellPane() { 
      addMouseListener(new MouseAdapter() { 
       @Override 
       public void mouseEntered(MouseEvent e) { 
        defaultBackground = getBackground(); 
        setBackground(Color.BLUE); 
       } 

       @Override 
       public void mouseExited(MouseEvent e) { 
        setBackground(defaultBackground); 
       } 
      }); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(50, 50); 
     } 
    } 
} 
+0

हैलो, मुझे एहसास है कि यह एक पुरानी पुरानी पोस्ट है। अरे @ मैडप्रोग्रामर, आपका कोड अद्भुत है!, मैंने इसे एक असाइनमेंट के लिए इसके साथ टिंकर करने के लिए पकड़ लिया, लेकिन मैं एक अचार में हूं, यह वही है जो मुझे चाहिए, लेकिन मुझे खिड़की 1080x760 बनाने, 1700 कोशिकाओं को बनाने और प्रत्येक सेल 20x20 बनाने की आवश्यकता है। अब मैंने खिड़की को फिर से बदल दिया है, और मैंने 1700 कोशिकाओं को बनाया है, मेरी समस्या यह है कि जब मैं कोशिकाओं को 20x20 में आकार देने का प्रयास करता हूं तो माउस श्रोता पागल हो जाता है और ठीक से काम नहीं करता ... मैंने कोशिश की है सेलविड्थ और सेलहेइट चर बदलना ... लेकिन यह इतना अच्छा काम नहीं कर रहा है ... कोई विचार? – Twhite1195

+0

@ Twhite1195 कौन सा संस्करण, पहला या दूसरा? – MadProgrammer

+0

@MadProgrammer सबसे पहले, दूसरा काम करता था ... जब तक मैंने कक्षों का आकार बदल दिया – Twhite1195

0

mouseMoved विधि में MouseListener उदाहरण में, आप xOffset/yOffset हालांकि विचार करने के लिए एक चिकनी सेल मान्यता के लिए चाहते हो सकता है।

int column = (x - xOffset)/cellWidth; 
int row = (y - yOffset)/cellHeight; 
1

मुझे ग्रिड के अंदर से सीमाओं को प्रतिपादित करना पसंद नहीं आया, उदाहरण के मुकाबले कुछ डुप्लिकेट किए गए थे। मुझे लगता है कि यह समाधान है कि बेहतर:

private int width; 
private int height; 

// ... 

for (int row = 0; row <= this.height; row++) { 
    for (int col = 0; col <= this.width; col++) { 
     gbc.gridx = col; 
     gbc.gridy = row; 

     CellPane cellPane = new CellPane(); 
     Border border = new MatteBorder(1, 1, (row == this.height ? 1 : 0), (col == this.width ? 1 : 0), Color.GRAY); 

     cellPane.setBorder(border); 
     this.add(cellPane, gbc); 
    } 
} 

संपादित करें:

मेरे समाधान, बेहतर है क्योंकि अगर मूल कोड 5x5 कोशिकाओं होगा, लेकिन अधिक है, जैसे 10x10 ... कुछ कोशिकाओं का भीतरी किनारा संपर्क में होगा और कुछ स्थानों को मोटी ग्रिड बनाने के लिए होगा। स्क्रीनशॉट thick grid

+0

क्या आप यह बता सकते हैं कि आपका समाधान इस मुद्दे को हल क्यों करता है? –

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