검색을 수행하는 간단한 Swing Java 응용 프로그램이 있으며 결과가 새 탭에 표시됩니다. 검색이 실행되는 동안 탭의 제목에 진행 아이콘이나 애니메이션을 표시하려고합니다. gif 아이콘을 추가하려고했지만 애니메이션이 적용되지 않습니다. 이것이 작동하지 않는 이유가 있습니까?JTabbedPane : 탭에 작업 진행률 표시
답변
Swing tutorial about progress bars (일반적으로 진행 상태를 보여줌)은 시작하기에 매우 좋은 장소입니다. SwingWorker
을 사용하여 작업자 스레드에서 오래 지속되는 작업을 수행하고 특정 간격으로 UI를 업데이트하여 오래 지속되는 작업의 진행 상황을 사용자에게 보여주는 방법을 보여줍니다. SwingWorker
and concurrency in Swing
에 대한 자세한 내용은 다른 튜토리얼을 참조하십시오. 언제나처럼이 사이트는 예제로 채워져 있습니다. 예를 들어 a previous answer of mine 내가 당신의 질문의 탭 부분의 제목을 놓친으로 사용자
편집
에 진행 상황을 보여주기 위해 SwingWorker
클래스를 사용합니다. '진행 아이콘'을 만들어 탭에서 설정할 수 있습니다. 그런 다음 SwingWorker
을 사용하여 아이콘을 업데이트 할 수 있습니다.
아이콘의 예는 입니다. 이는 기본적으로 진행될 때마다 회전하는 이미지입니다. 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.
나는 전체를 읽을 수 없다
이것은 모두 훌륭하지만, OP는 * 탭 자체에 진행 상황을 표시하려고합니다. 나는이 부분을 다루는 당신의 대답을 보지 못했다. –
아, 나는 tab_part의 _title을 보지 못했습니다. 단지 그가 tabbed pane을 사용하고 있다는 것입니다. 그렇다면 실제로 이것은 대답이 아닙니다. 이 회신에 유용한 것을 추가 할 수 있는지 또는 그렇지 않으면 삭제하는지 알 수 있습니다. – Robin
답변 주셔서 감사합니다. 그러나 제 경우에는이 방법을 사용할 수 없습니다 : 프로그램이 검색 진행 상황 (서버에서 수행)에 액세스 할 수 없습니다. 그래서 진행 아이콘을 표시하고 서버에서 응답을받을 때만 숨길 수 있습니다. – Paco
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();
}
});
}
}
우수! 관련 [예제] (http://stackoverflow.com/a/3484251/230513)도 참조하십시오. – trashgod
@trashgod Jeesh .. 내가 알고 있었음) a) 당신은 이미 멋진 맥 중 하나와 함께 b)에 대한 모범을 보았습니다. 스크린 샷.c) 나는 이미 선거에서 투표를했고, d) 몇 가지 '미친'순간에 해킹 할 수있는 것보다 낫다. (나는 여전히 내 접근법이 아무것도 무시할 필요가 없다는 점을 제외하고는,이 경우에는 "좋은 디자인"을 구성하는지, 아니면 단순히 죽은 말을 채찍질하는지 확실하지 않다.) –
나는이 두 가지를 모든 카운트에서 보완적인 것으로 본다. ; 인용했다. – trashgod
....하지만 당신에 의해 코드를 함께 넣어 @의 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;
}
}
}
또한'ColorPanel'에'JLabel'으로 추가 할 때 작동합니다. – trashgod
답장을 보내 주셔서 감사합니다. +1 :) –
이에 대한 '최소한 놀라움의 경로'에 대한 롭하여 지원을 metioned 탭 (선택된 탭 외부)은 선택된 탭의 진행 상황을 보여줍니다. * "어떤 제안? tnx"* 1) 그렇게하지 마십시오. 2) '감사'와 같은 단어를 올바르게 입력하거나 더 나은 단어로 남겨 두십시오. –
고마워,하지만 firefox의 탭 (로드 진행 상태를 보여주는 아이콘)과 같은 것을 알고 싶습니다. – Paco
글쎄, 헉,하지만 '우리는 기술'을 가지고 있으므로 내 대답을 참조하십시오. 치매를 입은 침팬지가 생각한 것처럼 보이지 않는 색상 (및 이미지 스타일 등)을 선택하는 것은 독자의 연습 과제로 남아 있습니다. –