【发布时间】:2025-02-06 18:55:02
【问题描述】:
当我从 Eclipse 运行我的程序时,GUI 是完美的,一切都很好。但是当我导出到 jar 文件(包含所有依赖项)时,它会运行,但 GUI 很奇怪,并且某些 UI 项目甚至没有出现(如您将在屏幕截图中看到的那样)。
我尝试导出为可运行的 jar,或者作为带有我自己的清单文件的普通 jar,我尝试从终端手动编译和链接到一个 jar(顺便说一下,我使用的是 linux mint)。我的项目合规性是在 java 1.8 上设置的,并且我的 PATH 中有 java 1.8,所以它看起来不像是版本不匹配。
奇怪的是,将我所有的源代码发送给一个运行 windows 的朋友,他能够链接到一个 jar 并运行它,并且运行良好。但问题并不是我的机器特有的,因为在另一台 linux 机器上运行它会产生完全相同的 GUI 错误。
如果有人能帮我解决这个问题,将不胜感激。
/**
* @author Garrit Nieuwoudt
*/
import java.io.File;
import java.util.ArrayList;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
public class MainPage {
private String iconDir ="."+File.separator+"images"+File.separator;
private Display disp;
private Shell shell;
private DatabaseHelper D;
private Tree tree;
private MainPage self;
private final Sash sash;
private Image icon;
private Table individualTable;
private Table markerTable;
private CTabFolder folder;
private Table resultTable;
private Table resultCheckTable;
private ArrayList<TestResult> allTestResults;
public MainPage(DatabaseHelper Dat){
allTestResults=new ArrayList<TestResult>();
this.self=this;
this.disp=Display.getCurrent();
D=Dat;
shell =new Shell(disp);
shell.setText(User.getCurrentUser().getName()+" - Genome Project");
icon=new Image(disp,iconDir+"blueDNA.png");
shell.setImage(icon);
FormLayout layout = new FormLayout();
shell.setLayout(layout);
createMenuBar();
sash = new Sash(shell, SWT.BORDER | SWT.VERTICAL |SWT.TRANSPARENT);
FormData formData = new FormData();
formData.top = new FormAttachment(0,40);
formData.left = new FormAttachment(15);
formData.bottom=new FormAttachment(100);
formData.width=3;
sash.setLayoutData(formData);
sash.addListener(SWT.Selection, new Listener () {
public void handleEvent(Event e) {
sash.setBounds(e.x, e.y, e.width, e.height);
if(e.x<=100){
e.doit=false;
}else{
sash.setEnabled(true);
FormData formData = new FormData();
formData.top = new FormAttachment(0, 0);
formData.left = new FormAttachment(0,e.x);
formData.bottom = new FormAttachment(100, 0);
formData.width=3;
sash.setLayoutData(formData);
shell.layout(true);
}
}
});
tree = new Tree(shell, SWT.VIRTUAL | SWT.BORDER );
tree.setToolTipText("Double click any tree item to load data to the table");
FormData treeData=new FormData();
treeData.left=new FormAttachment(0,3);
treeData.bottom=new FormAttachment(100,-50);
treeData.top=new FormAttachment(0,40);
treeData.right=new FormAttachment(sash,-1,SWT.LEFT);
tree.setLayoutData(treeData);
setTree();
tree.addListener(SWT.MouseDoubleClick, new Listener() {
@Override
public void handleEvent(Event event) {
int activeTab=folder.getSelectionIndex();
// TODO Auto-generated method stub
Point p=new Point(event.x,event.y);
TreeItem FT=tree.getItem(p);
if (activeTab==0) {
if (FT != null) {
individualTable.removeAll();
markerTable.removeAll();
int famIndex;
int dataIndex;
int fn;
if (FT.getParentItem() != null) {
famIndex = FT.getParentItem().indexOf(FT);
dataIndex = tree.indexOf(FT.getParentItem());
fn = famIndex + 1;
} else {
dataIndex = tree.indexOf(FT);
famIndex = 0;
fn = User.getCurrentUser().getDS().get(dataIndex).getFams().size();
}
for (int fi = famIndex; fi < fn; fi++) {
Family fam = User.getCurrentUser().getDS()
.get(dataIndex).getFams().get(fi);
for (int ii = 0; ii < fam.getMembers().size(); ii++) {
Individual ind = fam.getMembers().get(ii);
TableItem item = new TableItem(individualTable,
SWT.NULL);
item.setData("DS_ID", dataIndex);
item.setData("famIndex", fi);
item.setData("indIndex", ii);
item.setText(0, fam.getID());
item.setText(1, ind.getID());
item.setText(2, ind.getPatID());
item.setText(3, ind.getMatID());
item.setText(4, (ind.getGender() == 1) ? "Male"
: (ind.getGender() == 2) ? "Female"
: "Other");
item.setText(
5,
ind.getPhenotype() == 2 ? "Affected"
: (ind.getPhenotype() == 1) ? "Unaffected"
: "Missing");
}
}
for (int loopIndex = 0; loopIndex < individualTable.getColumnCount(); loopIndex++) {
individualTable.getColumn(loopIndex).pack();
}
}
}else if(activeTab==1){
if (FT != null) {
resultTable.removeAll();
resultCheckTable.removeAll();
allTestResults.clear();
int famIndex;
int dataIndex;
int fn;
if (FT.getParentItem() != null) {
famIndex = FT.getParentItem().indexOf(FT);
dataIndex = tree.indexOf(FT.getParentItem());
fn = famIndex + 1;
} else {
dataIndex = tree.indexOf(FT);
famIndex = 0;
fn = User.getCurrentUser().getDS().get(dataIndex).getFams().size();
}
for (int fi = famIndex; fi < fn; fi++) {
Family fam = User.getCurrentUser().getDS().get(dataIndex).getFams().get(fi);
TestResult res=GenomeTests.recTest(fam);
allTestResults.add(res);
res=GenomeTests.domTest(fam);
allTestResults.add(res);
//ArrayList<Marker> resMarkers=res.getCandidateMarkers();
}
for (int ri = 0; ri < allTestResults.size(); ri++) {
TestResult res=allTestResults.get(ri);
Family fam=res.getFam();
ArrayList<Marker> resMarkers=res.getCandidateMarkers();
ArrayList<Integer> resIndices=res.getIndices();
res.setDataIndex(dataIndex);
String label="";
if(res.getTestType()==1){
label="Recessive";
}else if(res.getTestType()==2){
label="Dominant";
}
for (int mi = 0; mi < resMarkers.size(); mi++) {
Marker mrk = resMarkers.get(mi);
TableItem item = new TableItem(resultTable,
SWT.NULL);
item.setData("DS_ID", res.getDataIndex());
item.setData("fam", fam);
//change this in table listener
item.setData("markIndex",resIndices.get(mi));
item.setText(0, fam.getID());
item.setText(1, mrk.getChromNum());
item.setText(2, mrk.getSNP());
item.setText(3, mrk.getBPPos() + "");
item.setText(4, label);
}
}
for (int loopIndex = 0; loopIndex < resultTable.getColumnCount(); loopIndex++) {
resultTable.getColumn(loopIndex).pack();
}
}
}
}
});
createTabFolder();
shell.open();
shell.forceFocus();
while(!shell.isDisposed()){
if(!disp.readAndDispatch()){
disp.sleep();
}
}
disp.dispose();
}
public void createMenuBar(){
Menu menuBar = new Menu(shell, SWT.BAR);
MenuItem fileMenuHeader = new MenuItem(menuBar, SWT.CASCADE);
fileMenuHeader.setText("&File");
Menu fileMenu = new Menu(shell, SWT.DROP_DOWN);
fileMenuHeader.setMenu(fileMenu);
MenuItem fileImportItem = new MenuItem(fileMenu, SWT.PUSH);
fileImportItem.setText("&Import");
fileImportItem.setToolTipText("Import a new set of data into the program");
fileImportItem.setImage(new Image(disp,iconDir+"importIcon.png"));
MenuItem fileSignoutItem = new MenuItem(fileMenu, SWT.PUSH);
fileSignoutItem.setText("&Sign out");
fileSignoutItem.setToolTipText("Return to the Login page");
MenuItem helpMenuHeader = new MenuItem(menuBar, SWT.CASCADE);
helpMenuHeader.setText("&Help");
Menu helpMenu = new Menu(shell, SWT.DROP_DOWN);
helpMenuHeader.setMenu(helpMenu);
MenuItem helpGetHelpItem = new MenuItem(helpMenu, SWT.PUSH);
helpGetHelpItem.setText("&Get Help");
fileImportItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e){
new ImportPage(D,self);
}
});
fileSignoutItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e){
shell.dispose();
new User(-1,null);
new LoginPage(D);
}
});
shell.setMenuBar(menuBar);
}
public void createTabFolder(){
folder = new CTabFolder(shell, SWT.BORDER );
folder.setSimple(false);
FormData tabData=new FormData();
tabData.left=new FormAttachment(sash,0,SWT.RIGHT);
tabData.right=new FormAttachment(100,-10);
tabData.top=new FormAttachment(tree,0,SWT.TOP);
tabData.bottom=new FormAttachment(tree,0,SWT.BOTTOM);
folder.setLayoutData(tabData);
//Tab 1
CTabItem tab1 = new CTabItem(folder,SWT.NONE);
tab1.setText("Details");
tab1.setImage(new Image(disp,iconDir+"smallDetails.png"));
folder.setSelection(tab1);
// Create the SashForm with HORIZONTAL
SashForm ssh=new SashForm(folder,SWT.HORIZONTAL);
//Tab 2
CTabItem tab2 = new CTabItem(folder, SWT.NULL);
tab2.setText("Genome Analysis");
tab2.setImage(new Image(disp,iconDir+"DNAtwist.png"));
setUpAnalysisPage(folder, tab2);
//_______________________________________________________________________
individualTable = new Table(ssh, SWT.BORDER | SWT.V_SCROLL| SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
individualTable.setHeaderVisible(true);
individualTable.setLinesVisible(true);
individualTable.setToolTipText("Click on a row to load data about the item");
String[] indTitles = { "Family ID","Individual ID","Paternal ID","Maternal ID","Gender","Affection Status" };
//set titles on individual details table
setTable(individualTable,indTitles);
markerTable = new Table(ssh, SWT.BORDER | SWT.V_SCROLL| SWT.H_SCROLL | SWT.MULTI );
markerTable.setHeaderVisible(true);
markerTable.setLinesVisible(true);
String[] markTitles = { "Chromosome", "SNP ID","Genetic distance","Base Pair Position","Allele 1","Allele 2" };
//set titles on marker table
setTable(markerTable,markTitles);
//add listener to populate marker table with selected individual genome data
individualTable.addListener(SWT.Selection,new Listener() {
@Override
public void handleEvent(Event e) {
// TODO Auto-generated method stub
TableItem itm=(TableItem) e.item;
Family fam=null;
Individual ind=User.getCurrentUser().getDS().get((int) itm.getData("DS_ID")).getFams().get((int)itm.getData("famIndex")).getMembers().get((int)itm.getData("indIndex"));
ArrayList<Genotype> G=ind.getGeno();
markerTable.removeAll();
for(int i=0;i<G.size();i++){
TableItem mItem = new TableItem(markerTable, SWT.NULL);
Genotype gt=G.get(i);
Marker M=gt.getMarker();
mItem.setText(0, M.getChromNum());
mItem.setText(1, M.getSNP());
mItem.setText(2, M.getDist()+"");
mItem.setText(3,M.getBPPos()+"");
mItem.setText(4,String.valueOf(gt.getBase1()));
mItem.setText(5,String.valueOf(gt.getBase2()));
}
for (int loopIndex = 0; loopIndex < markTitles.length; loopIndex++) {
markerTable.getColumn(loopIndex).pack();
}
}
});
tab1.setControl(ssh);
}
public void setUpAnalysisPage(CTabFolder folder,CTabItem tab){
Group comp=new Group(folder,SWT.NONE);
FormLayout lay=new FormLayout();
comp.setLayout(lay);
ToolBar tools=new ToolBar(comp,SWT.HORIZONTAL | SWT.FLAT );
ToolItem refine=new ToolItem(tools,SWT.CHECK);
refine.setImage(new Image(disp,iconDir+"filterIcon.png"));
refine.setToolTipText("Click here to refine the analysis results to specific tests");
Group refineGroup=new Group(comp,SWT.BORDER);
refineGroup.setLayout(new RowLayout(SWT.VERTICAL));
//ToolBar refineTools=new ToolBar(refineGroup,SWT.VERTICAL);
//refineGroup.setBackground(disp.getSystemColor(SWT.COLOR_TRANSPARENT));
Button check=new Button(refineGroup,SWT.CHECK );
check.setText("Recessive Test");
check.setSelection(true);
Button check1=new Button(refineGroup,SWT.CHECK );
check1.setText("Dominant Test");
check1.setSelection(true);
refineGroup.setVisible(false);
FormData toolData=new FormData();
toolData.top=new FormAttachment(0);
toolData.left=new FormAttachment(0);
tools.setLayoutData(toolData);
FormData refineGroupData=new FormData();
refineGroupData.top=new FormAttachment(tools,-10,SWT.BOTTOM);
refineGroupData.left=new FormAttachment(tools,10,SWT.LEFT);
refineGroup.setLayoutData(refineGroupData);
resultTable=new Table(comp, SWT.BORDER | SWT.V_SCROLL| SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
resultTable.setHeaderVisible(true);
resultTable.setLinesVisible(true);
resultTable.setToolTipText("Click on a row to load data about the item");
setTable(resultTable,new String[]{"Family ID","Chromosome Number","SNP","Base Pair Position","Indicating Test"});
FormData tableData=new FormData();
tableData.top=new FormAttachment(tools,0,SWT.BOTTOM);
tableData.left=new FormAttachment(0);
tableData.bottom=new FormAttachment(100);
tableData.right=new FormAttachment(60);
resultTable.setLayoutData(tableData);
resultCheckTable=new Table(comp, SWT.BORDER | SWT.V_SCROLL| SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
resultCheckTable.setHeaderVisible(true);
resultCheckTable.setLinesVisible(true);
setTable(resultCheckTable,new String[]{"Family ID","Individual ID","Affection Status","Allele 1","Allele 2"});
FormData checkTableData=new FormData();
checkTableData.top=new FormAttachment(tools,0,SWT.BOTTOM);
checkTableData.left=new FormAttachment(resultTable,0,SWT.RIGHT);
checkTableData.bottom=new FormAttachment(100);
checkTableData.right=new FormAttachment(100);
resultCheckTable.setLayoutData(checkTableData);
refine.addListener( SWT.Selection, new Listener() {
public void handleEvent(Event event) {
boolean refineStatus;
refineStatus=refineGroup.getVisible();
if(refineStatus){
resultTable.removeAll();
resultCheckTable.removeAll();
refineGroup.setVisible(false);
int[] indices= new int[refineGroup.getChildren().length];
for(int ci=0; ci<refineGroup.getChildren().length; ci++){
Button chk=(Button) refineGroup.getChildren()[ci];
if(chk.getSelection()){
indices[ci]=ci+1;
}else{
indices[ci]=-1;
}
}
populateResults(allTestResults, indices);
}else{
refineGroup.setVisible(true);
}
}
});
resultTable.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event e) {
TableItem itm=(TableItem) e.item;
Family fam=(Family) itm.getData("fam");
resultCheckTable.removeAll();
for(int i=0;i<fam.getMembers().size();i++){
TableItem mItem = new TableItem(resultCheckTable, SWT.NULL);
Individual ind=fam.getMembers().get(i);
Genotype gene=ind.getGeno().get((int)itm.getData("markIndex"));
Marker M=gene.getMarker();
mItem.setText(0,fam.getID());
mItem.setText(1, ind.getID());
mItem.setText(2, ind.getPhenotype() == 2 ? "Affected": (ind.getPhenotype() == 1) ? "Unaffected": "Missing");
mItem.setText(3, gene.getBase1()+"");
mItem.setText(4,gene.getBase2()+"");
if(ind.getPhenotype()==2){
mItem.setForeground(2, disp.getSystemColor(SWT.COLOR_DARK_CYAN));
if(gene.getBase1()==gene.getBase2()){
mItem.setForeground(3, disp.getSystemColor(SWT.COLOR_DARK_CYAN));
mItem.setForeground(4, disp.getSystemColor(SWT.COLOR_DARK_CYAN));
}
}
}
for (int loopIndex = 0; loopIndex < resultCheckTable.getColumnCount(); loopIndex++) {
resultCheckTable.getColumn(loopIndex).pack();
}
}
});
ToolItem zoom=new ToolItem(tools,SWT.PUSH);
zoom.setImage(new Image(disp,iconDir+"zoomIcon.png"));
zoom.setEnabled(false); //not yet implemented
tools.pack();
tab.setControl(comp);
}
public void setTree(){
ArrayList<DataSet> dat=User.getCurrentUser().getDS();
tree.setItemCount(dat.size());
for(int i=0;i<dat.size();i++){
DataSet d=dat.get(i);
ArrayList<Family> fam=d.getFams();
TreeItem DT=tree.getItem(i);
DT.setText("DataSet: "+(i+1));
DT.setImage(new Image(disp,iconDir+"DNAdata.png"));
DT.setItemCount(fam.size());
for(int j=0;j<fam.size();j++){
TreeItem FT= DT.getItem(j);
//System.out.println(fam.get(i).getID());
FT.setText(fam.get(j).getID());
FT.setImage(new Image(disp,iconDir+"familyIcon.png"));
}
}
}
/**
* Set table columns with titles
* @param table - The table whose columns are being set
* @param titles - The titles to set on the columns in respective order
*/
public void setTable(Table table,String[] titles){
for (int i = 0; i < titles.length; i++) {
TableColumn column = new TableColumn(table, SWT.NULL);
column.setText(titles[i]);
}
for (int i = 0; i < titles.length; i++) {
table.getColumn(i).pack();
}
}
public void populateResults(ArrayList<TestResult> res,int[] indices){
for(int ti=0;ti<indices.length;ti++){
if(indices[ti]>-1){
for(int ri=0;ri<res.size();ri++){
TestResult TR=res.get(ri);
if(TR.getTestType()==indices[ti]){
Family fam=TR.getFam();
ArrayList<Marker> resMarkers=TR.getCandidateMarkers();
ArrayList<Integer> resIndices=TR.getIndices();
String label="";
if(TR.getTestType()==1){
label="Recessive";
}else if(TR.getTestType()==2){
label="Dominant";
}
for (int mi = 0; mi < resMarkers.size(); mi++) {
Marker mrk = resMarkers.get(mi);
TableItem item = new TableItem(resultTable,
SWT.NULL);
item.setData("DS_ID", TR.getDataIndex());
item.setData("fam", fam);
//change this in table listener
item.setData("markIndex",resIndices.get(mi));
item.setText(0, fam.getID());
item.setText(1, mrk.getChromNum());
item.setText(2, mrk.getSNP());
item.setText(3, mrk.getBPPos() + "");
item.setText(4, label);
}
}
for (int loopIndex = 0; loopIndex < resultTable.getColumnCount(); loopIndex++) {
resultTable.getColumn(loopIndex).pack();
}
}
}
}
}
}
它在 Eclipse 中的外观:
从 JAR 中运行的样子:
【问题讨论】:
-
尝试提出一个显示问题的最小示例。我认为任何人都可以在不看代码的情况下提供帮助。
-
我的疯狂猜测是它与 gtk2 与 gtk3 有关,但如果没有 greg 提到的最小示例,我将无法做到两者。
-
好吧,我上传了最负责 GUI 的代码。
标签: java eclipse user-interface jar swt