2012-10-03 1 views
2

모두에게 좋은 날.슬라이드를 수행하는 동안 JDialog의 콘텐츠 창이 업데이트되지 않음

내가 달성하고자하는 것은 키보드를 사용하여 대화 상자를 만드는 것입니다. 그러나이 질문의 범위를 벗어납니다. 버튼을 누르면 아래쪽으로 밀어 넣어 프레임에 나타납니다.

저는 스윙 초보자입니다. 문제가 분명하면 비난하지 마십시오.
코드를 포기하고 (약간의 불완전 함을 가지고) 달성하지만 시작과 끝 위치 사이의 대화 상자의 실제 위치는 사용자에게 표시되지 않습니다. 대화 상자는 애니메이션이 끝나면 표시되지 않고 나타납니다. 왜 그들은 보여주지 않는지 아는 사람이 있습니까?

public class TestSliding 
extends JFrame { 

private static Window kbdOwner; 
private static final double kbdHeightRatio = 1d/4d; 
private static final long kbdSlideDurationMs = 3000; 

public static Point getKbdLocation() { 
    int x = (int) kbdOwner.getBounds().getLocation().getX(); 
    int y = 
    (int) (kbdOwner.getBounds().getLocation().getY() + kbdOwner.getBounds().getSize().getHeight() - getKbdSize() 
     .getHeight()); 

    return new Point(x, y); 
} 

public static Dimension getKbdSize() { 
    int width = (int) kbdOwner.getBounds().getSize().getWidth(); 
    int height = (int) (width * kbdHeightRatio); 

    return new Dimension(width, height); 
} 

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

    @Override 
    public void run() { 
     new TestSliding().setVisible(true); 
    } 
    }); 
} 

private JButton toogleBtn = new JButton("Toogle"); 
private VirtualKeyboardSlide slide; 

public TestSliding() { 
    super(); 
    kbdOwner = this; 
    setTitle("Test Sliding"); 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 
    setLayout(new BorderLayout()); 
    setBackground(Color.BLUE); 

    setResizable(false); 
    setSize(1024, 768); 

    toogleBtn.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent argE) { 
     switch (getSlide().getState()) { 
     case OUT: { 
      getSlide().in(); 
      break; 
     } 

     case IN: { 
      getSlide().out(); 
      break; 
     } 
     } 
    } 
    }); 

    JPanel panel = new JPanel(); 
    getContentPane().add(panel); 
    panel.add(toogleBtn); 
} 

public VirtualKeyboardSlide getSlide() { 
    if (slide == null) { 
    slide = new VirtualKeyboardSlide(); 
    slide.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 
    slide.pack(); 
    slide.setSize(getKbdSize()); 
    slide.setLocation(getKbdLocation()); 
    slide.setVisible(true); 
    } 

    return slide; 
} 

public interface IVirtualKeyboardPane { 
    public void in(); 
    public void out(); 
} 

public class VirtualKeyboardSlide 
.... 
// see below 
.... 

public class VirtualKeyboardPane 
.... 
// see below 
.... 

} 

대화 :

public enum KeyboardState { 
    SLIDING_IN, SLIDING_OUT, IN, OUT, DIED 
} 

대화의 내용 창은 다음 클래스로 표현된다 :

private class VirtualKeyboardSlide 
    extends JDialog { 

private static final long serialVersionUID = 1L; 

private KeyboardState kbdState_ = OUT; 

private double height; 
private double width; 

/** 
* Constructs a <code>VirtualKeyboardDialog</code>. 
*/ 
public VirtualKeyboardSlide() { 
    this(new VirtualKeyboardPane()); 
} 

public <T extends Container & IVirtualKeyboardPane> VirtualKeyboardSlide(T contentPane) { 
    super(kbdOwner, ModalityType.MODELESS); 
    setContentPane(contentPane); 
    setUndecorated(true); 
    setState(OUT); 
    setBackground(new Color(0, 0, 0, 0)); 
} 

/** 
* Returns the state of the keyboard 
* @return the state of the keyboard 
*/ 
public synchronized KeyboardState getState() { 
    return kbdState_; 
} 

public void in() { 
    if (canSlideIn()) { 
    setState(SLIDING_IN); 

    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
     getVirtualKeyboardPane().in(); 
     setState(IN); 
     } 
    }); 
    } 
} 

public void out() { 
    if (canSlideOut()) { 
    setState(SLIDING_OUT); 

    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
     getVirtualKeyboardPane().out(); 
     setState(OUT); 
     } 
    }); 
    } 
} 

/** 
* Sets the keyboard state 
* @param argState 
*/ 
public synchronized void setState(KeyboardState argState) { 
    kbdState_ = argState; 
} 

/** 
* Returns true if the keyboard can slide in now 
* @return true if the keyboard can slide in now 
*/ 
protected boolean canSlideIn() { 
    if (!getState().equals(OUT)) { 
    return false; 
    } 

    return true; 
} 

/** 
* Returns true if the keyboard can slide out now 
* @return true if the keyboard can slide out now 
*/ 
protected boolean canSlideOut() { 
    if (!getState().equals(IN)) { 
    return false; 
    } 

    return true; 
} 

protected IVirtualKeyboardPane getVirtualKeyboardPane() { 
    return (IVirtualKeyboardPane) getContentPane(); 
} 

} 

KeyboardState는 키보드의 상태를 정의하는 열거입니다

public class VirtualKeyboardPane 
    extends JPanel 
    implements IVirtualKeyboardPane { 

private static final long serialVersionUID = 1L; 

private int height_; 
private int width_; 

private int normalHeight_; 
private int normalWidth_; 

private int x_; 
private int y_; 

public VirtualKeyboardPane() { 
    super(); 
    setFocusable(false); 
    setOpaque(false); 
    setBorder(BorderFactory.createEmptyBorder()); 
} 

/** {@inheritDoc} */ 
@Override 
public void in() { 
    normalHeight_ = (int) getKbdSize().getHeight(); 
    normalWidth_ = (int) getKbdSize().getWidth(); 
    width_ = normalWidth_; 
    x_ = 0; 
    y_ = 0; 

    long currentTime = System.currentTimeMillis(); 
    long startTime = currentTime; 
    long endTime = currentTime + kbdSlideDurationMs; 

    height_ = 0; 
    while (currentTime < endTime) { 
    long elapsedTime = currentTime - startTime; 
    float f = ((float) elapsedTime/(float) kbdSlideDurationMs); 

    height_ = (int) (f * normalHeight_); 

    y_ = normalHeight_ - height_; 

    repaint(); 
    currentTime = System.currentTimeMillis(); 
    } 
} 

/** {@inheritDoc} */ 
@Override 
public void out() { 
    normalHeight_ = (int) getKbdSize().getHeight(); 
    normalWidth_ = (int) getKbdSize().getWidth(); 
    width_ = normalWidth_; 
    x_ = 0; 
    y_ = normalHeight_; 

    long currentTime = System.currentTimeMillis(); 
    long startTime = currentTime; 
    long endTime = currentTime + kbdSlideDurationMs; 

    height_ = normalHeight_; 
    while (currentTime < endTime) { 
    long elapsedTime = currentTime - startTime; 
    float f = ((float) elapsedTime/(float) kbdSlideDurationMs); 

    height_ = normalHeight_ - (int) (f * normalHeight_); 

    y_ = normalHeight_ - height_; 

    repaint(); 
    currentTime = System.currentTimeMillis(); 
    } 
} 

@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    g.setColor(new Color(RGBToFloat(255), RGBToFloat(255), RGBToFloat(255), 0.5f)); 
    // g.fillRect((int) x_, (int) y_, (int) width_, (int) height_); 
    g.fillRect(x_, y_, width_, height_); 
} 

private float RGBToFloat(int rgbValue) { 
    return (rgbValue - 0.5f)/255f; 
} 
} 

답변

2

T 문제는 사용자의 in()out()이 EDT에서 실행 중이며 끝날 때까지 차단하므로 Repaint 이벤트가 발송되지 않고 키보드의 수정 된 위치가 표시되는 것입니다.

대신 애니메이션을 페이스 할 때 스윙 타이머를 사용하십시오. 이렇게하면 중간 재 페인트가 실제로 발생할 수 있습니다.

+0

감사합니다. – user1712376

관련 문제