2013-11-04 4 views
2

은 내가 JLabel m_jlImageJScrollPane m_jScrollPane는 그 안에 표시되어 있습니다. m_jlImage은 사용자가 마지막으로 화면을 클릭했을 때 빨간색 점이 그려지는 화면 캡처입니다. m_jlImage의 빨간 점 위에 m_jScrollPane의보기 영역을 이동 (읽기 스크롤)하고 싶습니다. lastClick은 사용자가 클릭 한 마지막 위치이며 m_jlImage과 같은 좌표입니다.큰 이미지로보기 포트 이동하기. JLablel + JScrollPane의

이것은 내가 생각했던 것보다 더 어렵다는 것을 증명합니다.

나는 같은 축을 따라 화면의 전체 길이에 클릭 지점의 값의 비율을 얻고, 최대의 같은 비율로 해당 스크롤 막대를 이동하기로 결정했다. 이것은 화면에서 마지막으로 클릭 한 포인트가 왼쪽 상단에있는 경우에만 작동하는 것 같습니다.

내가 클릭 한 지점이 화면의 가장자리에있을 때 상황을 처리하는 방법을하지 확신합니다. 이 시나리오에서는 스크롤 막대가 같은 비율로 스크롤되도록 비율을 생성하지만 화면 가장자리에 있기 때문에 빨간색 점이 화면 밖으로 스크롤됩니다. 내가 이걸 어떻게 극복 할 수 있을지에 대한 제안이 있니?

public void scrollViewToLastClick() 
    { 
     int clckH = lastClick.y; 
     int clckW = lastClick.x; 

     int picH = this.m_jlImage.getHeight(); 
     int picW = this.m_jlImage.getWidth(); 

     int ratW = (int)(m_jScrollPane.getWidth()*(double)clckW/(double)picW); 
     int ratH = (int)(m_jScrollPane.getHeight()*(double)clckH/(double)picH); 

     m_jScrollPane.getHorizontalScrollBar().setValue(ratW); 
     m_jScrollPane.getVerticalScrollBar().setValue(ratH); 
    } 
+0

왜 단순히 사용하지) ['JComponent의 # scrollRectToVisble'] (http://docs.oracle.com/javase/7/docs/api/javax/swing/ 대신 JComponent.html # scrollRectToVisible (java.awt.Rectangle))? – MadProgrammer

+0

사용자가 'JLabel'을 클릭하고 있거나 라이브 화면을 녹화하고 있습니까? 간단한 실행 가능한 예제를 제공 할 수 있습니까? – MadProgrammer

+0

마우스 클릭을 캡쳐하기 위해'JNativeHook'을 이용하고 있습니다. 클릭이 발생하면 화면 캡쳐를하고 정보를'Image' 객체에 넣습니다. 마지막 클릭이 발생한 곳의 작은 빨간 점을 그립니다. JLabel의 아이콘을 편집 된 이미지로 만든 아이콘으로 설정하십시오. 그런 다음 위의 메서드를 호출하여 JLabel의 빨간색 점으로 스크롤 창을 스크롤합니다. –

답변

4

이것은 아주 기본적인 예입니다. 그것은 이미지 파일을 사용하여 스크롤바 안에 배치합니다 (라운드 방식으로).

는 거기에서, 단순히 무작위 (이미지의 범위 내에서) 포인트를 생성하는 스윙 Timer를 사용합니다.

새로운 포인트가 생성 될 때마다, 나는 단순히 그것을 위치와 내가 렌더링하려는 지점의 크기를 전달 scrollToRectVisible를 사용합니다. 이렇게하면 새 점 (및 점)이 스크롤 창 내에 표시됩니다.

enter image description here

이제
import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.FontMetrics; 
import java.awt.Graphics; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 
import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JLayeredPane; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.border.LineBorder; 

public class ScrollTest { 

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

    private JScrollPane scrollPane; 
    private DesktopPane desktopPane; 

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

       try { 
        desktopPane = new DesktopPane(); 
        scrollPane = new JScrollPane(desktopPane); 

        JFrame frame = new JFrame("Testing"); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.add(scrollPane); 
        frame.setSize(desktopPane.getPreferredSize().width/2, desktopPane.getPreferredSize().height/2); 
        frame.setLocationRelativeTo(null); 
        frame.setVisible(true); 
       } catch (IOException exp) { 
        exp.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public class DesktopPane extends JLayeredPane { 

     private List<Point> points; 

     public DesktopPane() throws IOException { 
      points = new ArrayList<>(25); 
      final BufferedImage img = ImageIO.read(new File("Desktop.jpg")); 
      final JLabel desktop = new JLabel(new ImageIcon(img)); 
      final JPanel overlay = new JPanel() { 

       @Override 
       protected void paintComponent(Graphics g) { 
        super.paintComponent(g); 
        int xOff = desktop.getX(); 
        int yOff = desktop.getY(); 
        int count = 0; 
        FontMetrics fm = g.getFontMetrics(); 
        int height = fm.getHeight(); 
        for (Point p : points) { 
         g.setColor(Color.RED); 
         String text = Integer.toString(++count); 
         int width = fm.stringWidth(text); 
         int radius = Math.max(width, height) + 5; 
         int x = xOff + p.x - radius/2; 
         int y = yOff + p.y - radius/2; 
         g.fillOval(x, y, radius, radius); 
         g.setColor(Color.WHITE); 
         x += (radius - width)/2; 
         y += ((radius - height)/2) + fm.getAscent(); 
         g.drawString(text, x, y); 
        } 
       } 
      }; 
      overlay.setOpaque(false); 

      setLayout(new GridBagLayout()); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.gridx = 0; 
      gbc.gridy = 0; 
      gbc.weightx = 1; 
      gbc.weighty = 1; 
      gbc.fill = GridBagConstraints.BOTH; 

      add(desktop, gbc); 
      add(overlay, gbc); 

      setLayer(desktop, 0); 
      setLayer(overlay, 5); 

      overlay.setBorder(new LineBorder(Color.RED)); 

      Timer timer = new Timer(1000, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        int x = (int) Math.round(Math.random() * img.getWidth()); 
        int y = (int) Math.round(Math.random() * img.getHeight()); 
        points.add(new Point(x, y)); 
        repaint(); 

        FontMetrics fm = getFontMetrics(overlay.getFont()); 
        int height = fm.getHeight(); 
        String text = Integer.toString(points.size() - 1); 
        int width = fm.stringWidth(text); 
        int radius = Math.max(width, height) + 5; 

        scrollRectToVisible(new Rectangle(x - radius/2, y - radius/2, radius, radius)); 
       } 
      }); 
      timer.start(); 
     } 
    } 
} 

, 추가 작업이 필요합니다 가능한 한 중심에 가깝게 점을 표시하려면 ... 이제

, 당신은 정말 재미를하려는 경우 50 같은 뭔가를 지연 설정 - 100 밀리 초를,