2012-02-22 30 views
5

Điều này có vẻ ngớ ngẩn (và nó có thể là) nhưng làm thế nào tôi có thể lật tất cả các thành phần trong một lộn ngược JFrame? Tất cả mọi thứ trong JFrame phải được lật dọc theo trục một nửa xuống JFrame bao gồm văn bản trên các điều khiển. Tốt hơn là với JTextField s, JButton s, v.v. hoạt động như mong đợi mặc dù bị lật.Làm thế nào để lật một JFrame và các con của nó lộn ngược?

Tôi đã thực hiện một số tìm kiếm nhưng không tìm thấy bất kỳ điều gì hữu ích về chủ đề này.

Có cách nào dễ dàng hơn thay đổi bố cục theo cách thủ công và sau đó mở rộng và ghi đè các phương pháp vẽ của từng điều khiển được sử dụng không?

EDIT: Tôi đã cố gắng làm cho nó hoạt động. Bạn có thể xem my answer below.

+2

* "quá nhiều công sức cho chỉ là một trò đùa đơn thuần?" * Bạn đã bao giờ xem xét sử dụng sức mạnh của bạn ..cho *** tốt? *** –

+0

Có thể dễ dàng lật màn hình của bạn xuống hoặc đứng trên đầu bạn. ;-) – DNA

+0

Rất nhiều thẻ đồ họa sẽ cho phép bạn xoay toàn bộ màn hình (nhưng không phải cửa sổ riêng lẻ), nếu điều đó sẽ cung cấp đầy đủ chế nhạo và giải trí? – DNA

Trả lời

2

Tôi đã quản lý để tạo một ứng dụng lật nhỏ. Cho đến nay tất cả các điều khiển con được sử dụng (JTextArea, JLabel, JButton) hoạt động như mong đợi, sự kiện và tất cả.

Đây là một ảnh chụp màn hình ...

It's flipped!

Và mã ...

import java.awt.AWTEvent; 
import java.awt.BorderLayout; 
import java.awt.Cursor; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Toolkit; 
import java.awt.Window; 
import java.awt.event.MouseEvent; 
import java.awt.geom.AffineTransform; 
import java.awt.image.AffineTransformOp; 
import java.awt.image.BufferedImage; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JRootPane; 
import javax.swing.JTextArea; 
import javax.swing.RepaintManager; 
import javax.swing.SwingUtilities; 
import javax.swing.border.EmptyBorder; 

public class FlipUpsideDown { 

    public static void main(String[] args) { 
     JTextArea textArea = new JTextArea("This is a working text area\n\nI LOVE SWING", 4, 0); 
     // The cursor still use the wrong mouse position so... 
     textArea.setCursor(Cursor.getDefaultCursor()); 

     final JPanel mainPanel = new JPanel(new BorderLayout(5, 5)); 

     mainPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     mainPanel.add(new JLabel("A Normal Label"), BorderLayout.NORTH); 
     mainPanel.add(textArea, BorderLayout.CENTER); 
     mainPanel.add(new JButton("Hello World!"), BorderLayout.SOUTH); 

     // The root pane is responsible for drawing all the children of the 
     // frame. All the paint calls go through the root pane since dirty 
     // painting of individual controls are blocked (see below). So we can 
     // use the paint method of the root pane to flip the painted controls. 
     final JFrame f = new JFrame("FlipUpsideDown") { 

      protected JRootPane createRootPane() { 
       JRootPane rp = new JRootPane() { 

        public void paint(Graphics g) { 
         BufferedImage im = new BufferedImage(this.getWidth(), this.getHeight(), 
           BufferedImage.TYPE_3BYTE_BGR); 
         // Paint normally but on the image 
         super.paint(im.getGraphics()); 

         // Reverse the image 
         AffineTransform tx = AffineTransform.getScaleInstance(1, -1); 
         tx.translate(0, -im.getHeight()); 
         AffineTransformOp op = new AffineTransformOp(tx, 
           AffineTransformOp.TYPE_NEAREST_NEIGHBOR); 
         im = op.filter(im, null); 

         // Draw the reversed image on the screen 
         g.drawImage(im, 0, 0, null); 
        } 
       }; 
       rp.setOpaque(true); 
       return rp; 
      } 
     }; 

     // Override the RepaintManager so that we always repaint the entire 
     // frame when a region is set to dirty. 
     RepaintManager repaintManager = new RepaintManager() { 

      public void addDirtyRegion(JComponent c, int x, int y, int w, int h) { 
       schedulePaint(); 
      } 

      public void addDirtyRegion(Window window, int x, int y, int w, int h) { 
       schedulePaint(); 
      } 

      public void paintDirtyRegions() { 
       schedulePaint(); 
      } 

      private void schedulePaint() { 
       SwingUtilities.invokeLater(new Runnable() { 

        @Override 
        public void run() { 
         f.paint(f.getGraphics()); 
        } 
       }); 
      } 
     }; 
     RepaintManager.setCurrentManager(repaintManager); 

     // Intercept mouse events and flip their positions around in the JFrame 
     EventQueue queue = new EventQueue() { 

      protected void dispatchEvent(AWTEvent event) { 
       if (event instanceof MouseEvent) { 
        MouseEvent me = (MouseEvent) event; 
        MouseEvent evt = new MouseEvent(
          me.getComponent(), 
          me.getID(), 
          me.getWhen(), 
          me.getModifiers(), 
          f.getWidth() - me.getX() + f.getInsets().right - f.getInsets().left, 
          f.getHeight() - me.getY() + f.getInsets().top - f.getInsets().bottom, 
          me.getClickCount(), 
          false, 
          me.getButton()); 
        event = evt; 
       } 
       super.dispatchEvent(event); 
      } 
     }; 
     Toolkit.getDefaultToolkit().getSystemEventQueue().push(queue); 

     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setLocationByPlatform(true); 
     f.add(mainPanel); 
     f.pack(); 
     f.setVisible(true); 
    } 
} 
+0

Bí quyết tuyệt vời với RepaintManager, sẽ không nghĩ đến điều đó. – ARRG

4

Bạn có thể dễ dàng lật GUI mà không cần phải sửa đổi tất cả các thành phần, chỉ cần thay đổi phương pháp sơn hàng đầu nhất-container của bạn:

class ReversedPanel extends Component { 
    @Override 
    public void paint(Graphics g) { 
     BufferedImage im = new BufferedImage(this.getWidth(), this.getHeight(), 
       BufferedImage.TYPE_3BYTE_BGR); 
     // Paint normally but on the image 
     super.paint(im.getGraphics()); 

     // Reverse the image 
     AffineTransform tx = AffineTransform.getScaleInstance(1, -1); 
     tx.translate(0, -im.getHeight()); 
     AffineTransformOp op = new AffineTransformOp(tx, 
       AffineTransformOp.TYPE_NEAREST_NEIGHBOR); 
     im = op.filter(im, null); 

     // Draw the reversed image on the screen 
     g.drawImage(im, 0, 0, null); 
    } 
} 

Ảo giác là không hoàn hảo mặc dù: khi người dùng di chuột qua bản gốc vị trí của một nút, nút sẽ được hiển thị chính xác.

Và rõ ràng điều này không quan tâm đến việc đảo ngược sự kiện, điều này phức tạp hơn nhiều.

+0

Cảm ơn câu trả lời của bạn! Đó là một khối xây dựng trong việc tạo ra ví dụ làm việc hoàn chỉnh. Nó thực sự là một nhiệm vụ để có được các sự kiện đảo ngược và sửa chữa các vấn đề sơn, nhưng tôi đã cố gắng để có được nó làm việc cuối cùng. – ughzan

Các vấn đề liên quan