2012-04-07 2 views
3

검색을 수행하는 간단한 Swing Java 응용 프로그램이 있으며 결과가 새 탭에 표시됩니다. 검색이 실행되는 동안 탭의 제목에 진행 아이콘이나 애니메이션을 표시하려고합니다. gif 아이콘을 추가하려고했지만 애니메이션이 적용되지 않습니다. 이것이 작동하지 않는 이유가 있습니까?JTabbedPane : 탭에 작업 진행률 표시

+0

이에 대한 '최소한 놀라움의 경로'에 대한 롭하여 지원을 metioned 탭 (선택된 탭 외부)은 선택된 탭의 진행 상황을 보여줍니다. * "어떤 제안? tnx"* 1) 그렇게하지 마십시오. 2) '감사'와 같은 단어를 올바르게 입력하거나 더 나은 단어로 남겨 두십시오. –

+0

고마워,하지만 firefox의 탭 (로드 진행 상태를 보여주는 아이콘)과 같은 것을 알고 싶습니다. – Paco

+1

글쎄, 헉,하지만 '우리는 기술'을 가지고 있으므로 내 대답을 참조하십시오. 치매를 입은 침팬지가 생각한 것처럼 보이지 않는 색상 (및 이미지 스타일 등)을 선택하는 것은 독자의 연습 과제로 남아 있습니다. –

답변

11

Swing tutorial about progress bars (일반적으로 진행 상태를 보여줌)은 시작하기에 매우 좋은 장소입니다. SwingWorker을 사용하여 작업자 스레드에서 오래 지속되는 작업을 수행하고 특정 간격으로 UI를 업데이트하여 오래 지속되는 작업의 진행 상황을 사용자에게 보여주는 방법을 보여줍니다. SwingWorker and concurrency in Swing

에 대한 자세한 내용은 다른 튜토리얼을 참조하십시오. 언제나처럼이 사이트는 예제로 채워져 있습니다. 예를 들어 a previous answer of mine 내가 당신의 질문의 탭 부분의 제목을 놓친으로 사용자

편집

에 진행 상황을 보여주기 위해 SwingWorker 클래스를 사용합니다. '진행 아이콘'을 만들어 탭에서 설정할 수 있습니다. 그런 다음 SwingWorker을 사용하여 아이콘을 업데이트 할 수 있습니다.

아이콘의 예는 example progress icon입니다. 이는 기본적으로 진행될 때마다 회전하는 이미지입니다. tabbed pane tutorial는 내 맥을 보인다으로 JDK1.7가 훨씬 쉽게 다음 애니메이션 GIF를 표시 할 수 있습니다 당신이 함께

Edit2가

을 (사용자 정의 구성 요소를 사용하는 경우에도 나) 당신의 탭에 아이콘을 추가하는 방법을 보여줍니다 다른 시스템에서는 앤드류와 비슷한 SSCCE를 만들었지 만 회전 아이콘은 만들어지지 않은 것처럼 보였습니다. 그리고 나는 '침팬지를 알아 챘습니다'라고 말합니다. 회전 아이콘 코드는 this site에서 가져옵니다 (필자는 버려진 버전을 사용하고 타이머를 추가했습니다). 내가 너무 행복하지 않은 점은 회전 된 아이콘에 탭 분할 창을 전달해야한다는 것입니다. 가능한 해결책은 RotatingIcon 클래스 외부에서 타이머를 가져 오는 것입니다.하지만 이건 단지 SSCCE 일뿐입니다. 이미지는 포함되지 않지만 Google에서 발견되었습니다.

import javax.swing.Icon; 
import javax.swing.ImageIcon; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JTabbedPane; 
import javax.swing.Timer; 
import java.awt.Component; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.AffineTransform; 

public class ProgressTabbedPane { 

    public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
     JFrame frame = new JFrame("RotatingIcon"); 
     JTabbedPane tabbedPane = new JTabbedPane(); 
     tabbedPane.addTab("Searching", new RotatingIcon(new ImageIcon("resources/images/progress-indeterminate.png"), tabbedPane), 
          new JLabel(new ImageIcon("resources/images/rotatingIcon.gif"))); 
     frame.getContentPane().add(tabbedPane); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 
     } 
    }); 
    } 

    private static class RotatingIcon implements Icon{ 
    private final Icon delegateIcon; 
    private double angleInDegrees = 90; 
    private final Timer rotatingTimer; 
    private RotatingIcon(Icon icon, final JComponent component) { 
     delegateIcon = icon; 
     rotatingTimer = new Timer(100, new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      angleInDegrees = angleInDegrees + 10; 
      if (angleInDegrees == 360){ 
      angleInDegrees = 0; 
      } 
      component.repaint(); 
     } 
     }); 
     rotatingTimer.setRepeats(false); 
     rotatingTimer.start(); 
    } 

    @Override 
    public void paintIcon(Component c, Graphics g, int x, int y) { 
     rotatingTimer.stop(); 
     Graphics2D g2 = (Graphics2D)g.create(); 
     int cWidth = delegateIcon.getIconWidth()/2; 
     int cHeight = delegateIcon.getIconHeight()/2; 
     Rectangle r = new Rectangle(x, y, delegateIcon.getIconWidth(), delegateIcon.getIconHeight()); 
     g2.setClip(r); 
     AffineTransform original = g2.getTransform(); 
     AffineTransform at = new AffineTransform(); 
     at.concatenate(original); 
     at.rotate(Math.toRadians(angleInDegrees), x + cWidth, y + cHeight); 
     g2.setTransform(at); 
     delegateIcon.paintIcon(c, g2, x, y); 
     g2.setTransform(original); 
     rotatingTimer.start(); 
    } 

    @Override 
    public int getIconWidth() { 
     return delegateIcon.getIconWidth(); 
    } 

    @Override 
    public int getIconHeight() { 
     return delegateIcon.getIconHeight(); 
    } 
    } 
} 

스크린 샷을 참조하십시오. 스크린 샷에서 아이콘이 회전하지 않는 것은 수치 스럽습니다. 앤드류 톰슨

It would be great if the J2SE supported animated GIFs 'out of the box' 
in more situations. I tried that animated GIF (nice image, BTW) as a 
tab icon, and no, it remains static. 

나는 전체를 읽을 수 없다 SSCCE screenshot

+0

이것은 모두 훌륭하지만, OP는 * 탭 자체에 진행 상황을 표시하려고합니다. 나는이 부분을 다루는 당신의 대답을 보지 못했다. –

+0

아, 나는 tab_part의 _title을 보지 못했습니다. 단지 그가 tabbed pane을 사용하고 있다는 것입니다. 그렇다면 실제로 이것은 대답이 아닙니다. 이 회신에 유용한 것을 추가 할 수 있는지 또는 그렇지 않으면 삭제하는지 알 수 있습니다. – Robin

+0

답변 주셔서 감사합니다. 그러나 제 경우에는이 방법을 사용할 수 없습니다 : 프로그램이 검색 진행 상황 (서버에서 수행)에 액세스 할 수 없습니다. 그래서 진행 아이콘을 표시하고 서버에서 응답을받을 때만 숨길 수 있습니다. – Paco

7

Animated image as tab icon

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

public class ImageOnTab { 

    ImageOnTab() { 

     final BufferedImage image = new BufferedImage(
      32,32,BufferedImage.TYPE_INT_RGB); 
     final JTabbedPane pane = new JTabbedPane(); 
     ImageIcon icon = new ImageIcon(image); 
     pane.addTab("Progress", icon, new JTree()); 

     ActionListener listener = new ActionListener() { 

      int x = 0; 
      int step = 1; 

      public void actionPerformed(ActionEvent ae) { 
       Graphics g = image.createGraphics(); 
       x+=step; 
       if (step>0) { 
        if (x>32) { 
         step=-step; 
        } 
       } else if (x<0) { 
        step=-step; 
       } 

       g.setColor(Color.ORANGE); 
       g.fillRect(0,0,32,32); 

       g.setColor(Color.RED); 
       g.fillRect(0,0,x,32); 

       g.dispose(); 

       pane.repaint(); 
      } 
     }; 

     Timer timer = new Timer(100,listener); 
     timer.start(); 

     JOptionPane.showMessageDialog(null, pane); 
    } 

    public static void main(String[] args) throws Exception { 
     //Create the GUI on the event dispatching thread 
     SwingUtilities.invokeLater(new Runnable(){ 
      @Override 
      public void run() { 
       new ImageOnTab(); 
      } 
     }); 
    } 
} 
+3

우수! 관련 [예제] (http://stackoverflow.com/a/3484251/230513)도 참조하십시오. – trashgod

+1

@trashgod Jeesh .. 내가 알고 있었음) a) 당신은 이미 멋진 맥 중 하나와 함께 b)에 대한 모범을 보았습니다. 스크린 샷.c) 나는 이미 선거에서 투표를했고, d) 몇 가지 '미친'순간에 해킹 할 수있는 것보다 낫다. (나는 여전히 내 접근법이 아무것도 무시할 필요가 없다는 점을 제외하고는,이 경우에는 "좋은 디자인"을 구성하는지, 아니면 단순히 죽은 말을 채찍질하는지 확실하지 않다.) –

+2

나는이 두 가지를 모든 카운트에서 보완적인 것으로 본다. ; 인용했다. – trashgod

4

....하지만 당신에 의해 코드를 함께 넣어 @의 trashgod의가) (나) 일반 HTML에 좋은 아니에요

2)) JLabel#(setOpaque(true))

3 GlassPane를 사용 JLayer을 사용 (Htlm를 사용 JXLayer

1 위엄 더 Sn'Oracle를 변경할 수 없기 당신은 force ..... for Swing JComponents by @aterai

5)에있다) 중요한 방법 == 내보기)

4 제거 957,613,210 몇 번 관심의 탭 또는 일반적인 진행의 구성 요소 사이 중 하나`JProgressBar` 것 JTabbedPane

코드

import java.awt.*; 
import java.awt.event.*; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.Random; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.*; 
//https://stackoverflow.com/questions/3483485/java-jprogressbar-or-equivalent-in-a-jtabbedpane-tab-title/3484251#3484251 
public class JTabbedTest { 

    private JFrame f = new JFrame(); 
    private JTabbedPane jtp = new JTabbedPane(); 
    private URL url = null; 

    public JTabbedTest() { 
     try { 
      url = new URL("http://pscode.org/media/starzoom-thumb.gif"); 
     } catch (MalformedURLException ex) { 
      Logger.getLogger(JTabbedTest.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     ImageIcon ii = new ImageIcon(url); 

     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     jtp.setPreferredSize(new Dimension(400, 200)); 
     createTab("Reds", Color.RED); 
     createTab("Greens", Color.GREEN); 
     createTab("Blues", Color.BLUE); 
     f.add(jtp, BorderLayout.CENTER); 

     jtp.setTitleAt(2, "<html><img src=" + ii + " width=20 height=20></img></html>"); 

     // change foreground Color for disabled tab   
     /*jtp.setTitleAt(2, "<html><font color=" + (jtp.isEnabledAt(2) ? "black" : "red") + ">" 
       + jtp.getTitleAt(2) + "</font></html>");*/ 

     Rectangle tabBounds = jtp.getBoundsAt(0); 
     Container glassPane = (Container) f.getRootPane().getGlassPane(); 
     glassPane.setVisible(true); 
     glassPane.setLayout(new GridBagLayout()); 
     GridBagConstraints gbc = new GridBagConstraints(); 
     gbc.weightx = 1.0; 
     gbc.weighty = 1.0; 
     gbc.fill = GridBagConstraints.NONE; 
     gbc.insets = new Insets(tabBounds.y + 23, 0, 0, 5); 
     gbc.anchor = GridBagConstraints.NORTHEAST; 
     JButton button = new JButton("My Button Position", ii); 
     button.setPreferredSize(new Dimension(button.getPreferredSize().width, (int) tabBounds.getHeight() - 2)); 
     glassPane.add(button, gbc); 
     f.pack(); 
     f.setVisible(true); 
    } 

    private void createTab(String name, Color color) { 
     ProgressIcon icon = new ProgressIcon(color); 
     jtp.addTab(name, icon, new ColorPanel(jtp, icon)); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       JTabbedTest jTabbedTest = new JTabbedTest(); 
      } 
     }); 
    } 

    private static class ColorPanel extends JPanel implements ActionListener { 

     private static final Random rnd = new Random(); 
     private static final long serialVersionUID = 1L; 
     private final Timer timer = new Timer(1000, this); 
     private final JLabel label = new JLabel("Stackoverflow!"); 
     private final JTabbedPane parent; 
     private final ProgressIcon icon; 
     private final int mask; 
     private int count; 

     public ColorPanel(JTabbedPane parent, ProgressIcon icon) { 
      super(true); 
      this.parent = parent; 
      this.icon = icon; 
      this.mask = icon.color.getRGB(); 
      this.setBackground(icon.color); 
      label.setForeground(icon.color); 
      this.add(label); 
      timer.start(); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      this.setBackground(new Color(rnd.nextInt() & mask)); 
      this.icon.update(count += rnd.nextInt(8)); 
      this.parent.repaint(); 
     } 
    } 

    private static class ProgressIcon implements Icon { 

     private static final int H = 16; 
     private static final int W = 3 * H; 
     private Color color; 
     private int w; 

     public ProgressIcon(Color color) { 
      this.color = color; 
     } 

     public void update(int i) { 
      w = i % W; 
     } 

     @Override 
     public void paintIcon(Component c, Graphics g, int x, int y) { 
      g.setColor(color); 
      g.fillRect(x, y, w, H); 
     } 

     @Override 
     public int getIconWidth() { 
      return W; 
     } 

     @Override 
     public int getIconHeight() { 
      return H; 
     } 
    } 
} 
+2

또한'ColorPanel'에'JLabel'으로 추가 할 때 작동합니다. – trashgod

+1

답장을 보내 주셔서 감사합니다. +1 :) –