首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

J2SE 关于JPanel的页面跳转有关问题

2012-12-15 
J2SE 关于JPanel的页面跳转问题小弟目前在用Swing做一个桌面应用程序遇到一个问题就是JPanel的页面不能正

J2SE 关于JPanel的页面跳转问题
小弟目前在用Swing做一个桌面应用程序遇到一个问题就是JPanel的页面不能正常跳转。
比如下面的代码:



else if ("确定出票" == ((JButton) btn).getName()) {
if (btn == e.getSource()) {
System.out.println("确定出票被点击了");
TvmFrame.getInstance().remove(StationCashTicket.getInstance());
TvmFrame.getInstance().remove(StationCardTicket.getInstance());
TvmFrame.getInstance().remove(PriceCardTicket.getInstance());
TvmFrame.getInstance().remove(PriceCashTicket.getInstance());
TvmFrame.getInstance().add(Ticketing.getInstance()); //始终不能正常的跳到这个页面
TvmFrame.getInstance().repaint();
if (sellingOneWayTicket.sellTickets()) {
System.out.println("开始压币");
coinModulServiceImpl.startManage();
coinModulServiceImpl.stopManage();
} else {
// 当机器出现故障出票失败时将硬币全部退出
coinModulServiceImpl.changeCoin(coinModulServiceImpl.get1NoOfCoin(),0);
coinModulServiceImpl.outCoin();//很多时候都如果出现问题的话都是直接跳到这个页面,上面红色字体的那个页面直接过了
}
}

} else if ("重选站台" == ((JButton) btn).getName()) {

按照逻辑应该是先跳到Ticketing这个页面然后根据sellingOneWayTicket.sellTickets()的执行过程跳到另外一个页面

sellTickets的代码如下:


public boolean sellTickets() {
try {
if (cardSenderService.establishCommu()) {
System.out.println("建立通信成功!");
if (Calculatefares.totalTicketPrice == Calculatefares.coinNumber) {
System.out.println("投币金额足够");
System.out.println("Calculatefares.ticketNumber :"+Calculatefares.ticketNumber );
while (Calculatefares.ticketNumber > 0) {
if (cardSenderService.issueCardToCardreader()) {
System.out.println("出票到写卡器");
if (ticketCardReaderService.writeCard()) {
System.out.println("写卡成功");
if (cardSenderService.issueCardToOutlet()) {
//出卡到客户成功
System.out.println("出票到客户");
TvmFrame.getInstance().remove(Ticketing.getInstance());
TvmFrame.getInstance().add(TicketSuccess.getInstance());
TvmFrame.getInstance().repaint();
Thread.sleep(1000);
TvmFrame.getInstance().remove(TicketSuccess.getInstance());
TvmFrame.getInstance().add(Map.getInstance());
TvmFrame.getInstance().add(TicketPanel.getInstance());
TvmFrame.getInstance().add(StationPanel.getInstance());
TvmFrame.getInstance().add(LinePanel.getInstance());
//ThreadPool.getInstance().getThreadPool().execute(TicketNumberHandler.calculatefares); // 购票线程,当客户选择站点后开启
} else {
//出卡到客户失败
TvmFrame.getInstance().remove(Ticketing.getInstance());
TvmFrame.getInstance().add(Error.getInstance());
TvmFrame.getInstance().repaint();
cardSenderService.callBackCard();
Thread.sleep(1000);
return false;

}
} else {
// 写卡失败
TvmFrame.getInstance().remove(Ticketing.getInstance());
TvmFrame.getInstance().add(Error.getInstance());
TvmFrame.getInstance().repaint();
return false;
}
} else {
// 出票到读卡器失败
TvmFrame.getInstance().remove(Ticketing.getInstance());
TvmFrame.getInstance().add(Error.getInstance());
TvmFrame.getInstance().repaint();
return false;
}
Calculatefares.ticketNumber--;
Thread.sleep(300);
}
}
} else {


// 通信故障
TvmFrame.getInstance().remove(Ticketing.getInstance());
TvmFrame.getInstance().add(Error.getInstance());
Error.getInstance().updateUI();
TvmFrame.getInstance().repaint();
return false;
}
} catch (Exception e) {
//售票的过程中抛出了异常
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
e.printStackTrace();
System.out.println("售票出现异常,请检查硬币机,读卡器,写卡器是否正常工作!");
TvmFrame.getInstance().remove(Ticketing.getInstance());
TvmFrame.getInstance().add(Error.getInstance());
TvmFrame.getInstance().repaint();
return false;
}
return false;
}

请问为什么这些Jpanel为什么不能按照正常的逻辑跳转呢?

Note:sellTickets这个方法要操作硬件

[最优解释]

2楼的 CardLayout +1
多层的切换最好用 CardLayout


然后,你的问题实际上是没有理解 Swing 的线程。
如果我没猜错的话,你所有的代码,都是写在同一个 actionPerformed() 里面的。


TvmFrame.getInstance().add(Ticketing.getInstance()); //始终不能正常的跳到这个页面
TvmFrame.getInstance().repaint();


这两句代码说,我换了一个panel,重绘一下。

EDT说,好的,repaint()事件已经排进我的队列里了(repaint()是非同步调用,它把一个repaint事件排进EDT队列里就返回,并不是立时就重绘),顺便说一句,我现在所有的时间都用在执行你这个actionPerformed方法本身,在你执行完以前,队列里所有排在你后面的事件都要等。

然后,在这个方法稍后面一点的地方,你又写了一些逻辑,换了另外一个页面,
也就是说,你换成Ticketing.getInstance()以后,还没有来得及重绘,就又换了另一个页面。

解决方案: 可以把actionPerformed拆成两半,你换了Ticketing.getInstance()页面,送出一个重绘请求,然后说,后面还有一些逻辑,但是我想把它们排在重绘之后:


// ...
if (btn == e.getSource()) {

  System.out.println("确定出票被点击了");
  TvmFrame.getInstance().remove(StationCashTicket.getInstance());
  TvmFrame.getInstance().remove(StationCardTicket.getInstance());
  TvmFrame.getInstance().remove(PriceCardTicket.getInstance());
  TvmFrame.getInstance().remove(PriceCashTicket.getInstance());
  TvmFrame.getInstance().add(Ticketing.getInstance()); //始终不能正常的跳到这个页面
  TvmFrame.getInstance().repaint();
  
  SwingUtilities.invokeLater(new Runnable() {
  
    @Override
    public void run() {
    
      if (sellingOneWayTicket.sellTickets()) {
        System.out.println("开始压币");
        coinModulServiceImpl.startManage();
        coinModulServiceImpl.stopManage();
      } else {
        // 当机器出现故障出票失败时将硬币全部退出
        coinModulServiceImpl.changeCoin(coinModulServiceImpl.get1NoOfCoin(),0);
        coinModulServiceImpl.outCoin();//很多时候都如果出现问题的话都是直接跳到这个页面,上面红色字体的那个页面直接过了
      }
    }
  });
}
// ...


[其他解释]
太乱了。

在一个容器内切换显示可以使用 CardLayout布局管理器。
[其他解释]
自己顶一下 
上面的代码有点乱

补充一下:

TvmFrame.getInstance().remove(StationCashTicket.getInstance());
TvmFrame.getInstance().remove(StationCardTicket.getInstance());
TvmFrame.getInstance().remove(PriceCardTicket.getInstance());


TvmFrame.getInstance().remove(PriceCashTicket.getInstance());
TvmFrame.getInstance().add(Ticketing.getInstance());
TvmFrame.getInstance().repaint();
if(true)
{
TvmFrame.getInstance().remove(Ticketing.getInstance());
TvmFrame.getInstance().add(TicketSuccess.getInstance());
TvmFrame.getInstance().repaint();
}

假如是这样为什么不能实现连续2个Panel(Ticketing,TicketSuccess)的跳转呢?















[其他解释]
不好意思 确实有点乱了

下面我详细说下:

假如说我有3个JPanel,分别是Panel1,Panel2,Panel3,panel4
在Panel1上有一个button btn,btn 上被我添加了一个鼠标点击事件,这个鼠标点击事件是和一些
硬件操作有关

当我在panel1上点击btn时,就会进行一些硬件操作,这是应该跳到panel2(这个Panel上有一个进度条显示
操作的进度),当事件处理完成后就要根据事件执行的结果跳到panel3(执行成功页面),或者跳到Panel4(执行失败页面)。

但是我现在的问题是每当我在panel1上点击btn时,要么执行 成功跳到panel3要么执行失败跳到Panel4
请问这是什么原因呢?是不是因为我当中有硬件操作的原因呢?

[其他解释]
自己顶一下
[其他解释]
有没有哪位大侠帮忙看下呢?

[其他解释]
非常感谢楼主的回复,最近这几天太忙了,一直没时间上csdn.是的
所有的代码都在同一个actionperformed里面。看了你讲的感觉很清晰,我在家里的电脑的上试了下但是好像还是无法跳转样。明天到了公司了加上那些硬件再测试下,非常感谢了。
[其他解释]

引用:
非常感谢楼主的回复,最近这几天太忙了,一直没时间上csdn.是的
所有的代码都在同一个actionperformed里面。看了你讲的感觉很清晰,我在家里的电脑的上试了下但是好像还是无法跳转样。明天到了公司了加上那些硬件再测试下,非常感谢了。


不谢,除了6楼的更改之外,这一句:

TvmFrame.getInstance().repaint();


前面加一句:

TvmFrame.getInstance().invalidate();
TvmFrame.getInstance().repaint();


当一个容器布局内的子控件发生变化的时候,比如删掉了一些子控件,又添加了一些子控件,这时调用 invalidate(),告诉Swing的repaint机制:这个容器内的内容改变了,在下一次重绘之前需要重新计算布局(就是为它里面的子控件重新计算大小和位置,会触发其注册的LayoutManager的layoutContainer方法)。


[其他解释]
TvmFrame.getInstance().invalidate();

写错了,应该是

TvmFrame.getInstance().getContentPane().invalidate();
[其他解释]
刚试了一下,确实可以了,非常感谢您!!1

热点排行