祝大家有美好的一天。
我想要实现的是,当按下按钮时,通过从底部滑入,在框架上出现一个对话框(带有键盘,但这超出了这个问题的范围)。
我是挥杆初学者,如果问题很明显,请不要责怪。
我抛出了一些代码,实现了这一点(有一些缺陷),但没有向用户显示开始和结束位置之间对话的实际位置。动画完成后会出现对话框,但不显示。有谁知道为什么不显示?
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
....
}
对话框:
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 enum KeyboardState {
SLIDING_IN, SLIDING_OUT, IN, OUT, DIED
}
对话框的内容窗格由以下类表示:
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;
}
}