/******************************************************************************* * Copyright (c) 2016 Weasis Team and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nicolas Roduit - initial API and implementation *******************************************************************************/ package org.weasis.dicom.explorer; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.font.FontRenderContext; import java.beans.PropertyChangeEvent; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JSlider; import javax.swing.JToggleButton; import javax.swing.JViewport; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; import javax.swing.border.TitledBorder; import org.dcm4che3.data.Tag; import org.slf4j.LoggerFactory; import org.weasis.core.api.explorer.DataExplorerView; import org.weasis.core.api.explorer.ObservableEvent; import org.weasis.core.api.explorer.model.DataExplorerModel; import org.weasis.core.api.gui.util.AbstractItemDialogPage; import org.weasis.core.api.gui.util.ActionW; import org.weasis.core.api.gui.util.GuiExecutor; import org.weasis.core.api.gui.util.JMVUtils; import org.weasis.core.api.media.data.MediaSeries; import org.weasis.core.api.media.data.MediaSeriesGroup; import org.weasis.core.api.media.data.MediaSeriesGroupNode; import org.weasis.core.api.media.data.Series; import org.weasis.core.api.media.data.SeriesThumbnail; import org.weasis.core.api.media.data.TagW; import org.weasis.core.api.media.data.Thumbnail; import org.weasis.core.api.service.BundleTools; import org.weasis.core.api.util.FontTools; import org.weasis.core.api.util.StringUtil; import org.weasis.core.ui.docking.PluginTool; import org.weasis.core.ui.editor.SeriesViewer; import org.weasis.core.ui.editor.SeriesViewerEvent; import org.weasis.core.ui.editor.SeriesViewerEvent.EVENT; import org.weasis.core.ui.editor.SeriesViewerListener; import org.weasis.core.ui.editor.image.ImageViewerPlugin; import org.weasis.core.ui.editor.image.ViewCanvas; import org.weasis.core.ui.editor.image.ViewerPlugin; import org.weasis.core.ui.util.ArrayListComboBoxModel; import org.weasis.core.ui.util.ColorLayerUI; import org.weasis.core.ui.util.DefaultAction; import org.weasis.core.ui.util.TitleMenuItem; import org.weasis.core.ui.util.WrapLayout; import org.weasis.dicom.codec.DicomSpecialElement; import org.weasis.dicom.codec.KOSpecialElement; import org.weasis.dicom.codec.TagD; import org.weasis.dicom.codec.TagD.Level; import org.weasis.dicom.explorer.wado.LoadSeries; import bibliothek.gui.dock.common.CLocation; import bibliothek.gui.dock.common.mode.ExtendedMode; public class DicomExplorer extends PluginTool implements DataExplorerView, SeriesViewerListener { private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(DicomExplorer.class); public static final String NAME = Messages.getString("DicomExplorer.title"); //$NON-NLS-1$ public static final String PREFERENCE_NODE = "dicom.explorer"; //$NON-NLS-1$ public static final String BUTTON_NAME = Messages.getString("DicomExplorer.btn_title"); //$NON-NLS-1$ public static final String DESCRIPTION = Messages.getString("DicomExplorer.desc"); //$NON-NLS-1$ public static final String ALL_PATIENTS = Messages.getString("DicomExplorer.sel_all_pat"); //$NON-NLS-1$ public static final String ALL_STUDIES = Messages.getString("DicomExplorer.sel_all_st"); //$NON-NLS-1$ public static final Icon PATIENT_ICON = new ImageIcon(DicomExplorer.class.getResource("/icon/16x16/patient.png")); //$NON-NLS-1$ public static final Icon KO_ICON = new ImageIcon(DicomExplorer.class.getResource("/icon/16x16/key-images.png")); // $NON-NLS-0$ //$NON-NLS-1$ private JPanel panel = null; private PatientPane selectedPatient = null; private final List<PatientPane> patientPaneList = new ArrayList<>(); private final HashMap<MediaSeriesGroup, List<StudyPane>> patient2study = new HashMap<>(); private final HashMap<MediaSeriesGroup, List<SeriesPane>> study2series = new HashMap<>(); private final JScrollPane thumnailView = new JScrollPane(); private final LoadingPanel loadingPanel = new LoadingPanel(); private final SeriesSelectionModel selectionList; private final DicomModel model; private final ArrayListComboBoxModel<Object> modelPatient = new ArrayListComboBoxModel<>(DicomSorter.PATIENT_COMPARATOR); private final ArrayListComboBoxModel<Object> modelStudy = new ArrayListComboBoxModel<>(DicomSorter.STUDY_COMPARATOR); private final JComboBox<?> patientCombobox = new JComboBox<>(modelPatient); private final JComboBox<?> studyCombobox = new JComboBox<>(modelStudy); protected final PatientContainerPane patientContainer = new PatientContainerPane(); private final transient ItemListener patientChangeListener = e -> { if (e.getStateChange() == ItemEvent.SELECTED) { Object item = modelPatient.getSelectedItem(); if (item instanceof MediaSeriesGroupNode) { MediaSeriesGroupNode patient = (MediaSeriesGroupNode) item; selectPatient(patient); } else if (item != null) { selectPatient(null); } patientContainer.revalidate(); patientContainer.repaint(); } }; private final transient ItemListener studyItemListener = e -> { if (e.getStateChange() == ItemEvent.SELECTED) { selectStudy(); } }; private final JSlider slider = new JSlider(Thumbnail.MIN_SIZE, Thumbnail.MAX_SIZE, Thumbnail.DEFAULT_SIZE); private JPanel panelMain = null; private final JToggleButton btnMoreOptions = new JToggleButton(Messages.getString("DicomExplorer.more_opt")); //$NON-NLS-1$ private boolean verticalLayout = true; private final JButton btnExport; private final JButton btnImport; private final JButton koOpen = new JButton(Messages.getString("DicomExplorer.open_ko"), KO_ICON); //$NON-NLS-1$ public DicomExplorer() { this(null); } public DicomExplorer(DicomModel model) { super(BUTTON_NAME, NAME, POSITION.WEST, ExtendedMode.NORMALIZED, PluginTool.Type.EXPLORER, 20); setLayout(new BorderLayout()); setDockableWidth(180); dockable.setMaximizable(true); this.model = model == null ? new DicomModel() : model; this.selectionList = new SeriesSelectionModel(patientContainer); thumnailView.getVerticalScrollBar().setUnitIncrement(16); thumnailView.setViewportView(patientContainer); this.btnImport = new JButton(new DefaultAction(BUTTON_NAME, event -> { if (BundleTools.SYSTEM_PREFERENCES.getBooleanProperty("weasis.import.dicom", true)) { //$NON-NLS-1$ ColorLayerUI layer = ColorLayerUI.createTransparentLayerUI(DicomExplorer.this); DicomImport dialog = new DicomImport(SwingUtilities.getWindowAncestor(DicomExplorer.this), model); dialog.showPage(BUTTON_NAME); ColorLayerUI.showCenterScreen(dialog, layer); } else { JOptionPane.showMessageDialog((Component) event.getSource(), Messages.getString("DicomExplorer.export_perm")); //$NON-NLS-1$ } })); this.btnExport = new JButton(new DefaultAction(BUTTON_NAME, event -> { if (BundleTools.SYSTEM_PREFERENCES.getBooleanProperty("weasis.export.dicom", true)) { //$NON-NLS-1$ ColorLayerUI layer = ColorLayerUI.createTransparentLayerUI(DicomExplorer.this); DicomExport dialog = new DicomExport(SwingUtilities.getWindowAncestor(DicomExplorer.this), model); dialog.showPage(BUTTON_NAME); ColorLayerUI.showCenterScreen(dialog, layer); } else { JOptionPane.showMessageDialog((Component) event.getSource(), Messages.getString("DicomExplorer.export_perm")); //$NON-NLS-1$ } })); changeToolWindowAnchor(getDockable().getBaseLocation()); } public SeriesSelectionModel getSelectionList() { return selectionList; } private void removePatientPane(MediaSeriesGroup patient) { for (int i = 0; i < patientPaneList.size(); i++) { PatientPane p = patientPaneList.get(i); if (p.isPatient(patient)) { patientPaneList.remove(i); List<StudyPane> studies = patient2study.remove(patient); if (studies != null) { for (StudyPane studyPane : studies) { study2series.remove(studyPane.dicomStudy); } } patientContainer.remove(p); modelPatient.removeElement(patient); if (modelPatient.getSize() == 0) { modelStudy.removeAllElements(); modelStudy.insertElementAt(ALL_STUDIES, 0); modelStudy.setSelectedItem(ALL_STUDIES); koOpen.setVisible(false); } return; } } } private void removeStudy(MediaSeriesGroup study) { MediaSeriesGroup patient = model.getParent(study, DicomModel.patient); List<StudyPane> studies = patient2study.get(patient); if (studies != null) { for (int i = 0; i < studies.size(); i++) { StudyPane st = studies.get(i); if (st.isStudy(study)) { studies.remove(i); if (studies.isEmpty()) { patient2study.remove(patient); // throw a new event for removing the patient model.removePatient(patient); break; } study2series.remove(study); PatientPane patientPane = getPatientPane(patient); if (patientPane != null && patientPane.isStudyVisible(study)) { patientPane.remove(st); modelStudy.removeElement(study); patientPane.revalidate(); patientPane.repaint(); } return; } } } study2series.remove(study); } private void removeSeries(MediaSeriesGroup series) { MediaSeriesGroup study = model.getParent(series, DicomModel.study); List<SeriesPane> seriesList = study2series.get(study); if (seriesList != null) { for (int j = 0; j < seriesList.size(); j++) { SeriesPane se = seriesList.get(j); if (se.isSeries(series)) { seriesList.remove(j); if (seriesList.isEmpty()) { study2series.remove(study); // throw a new event for removing the patient model.removeStudy(study); break; } se.removeAll(); StudyPane studyPane = getStudyPane(study); if (studyPane != null && studyPane.isSeriesVisible(series)) { studyPane.remove(se); studyPane.revalidate(); studyPane.repaint(); } break; } } } } private PatientPane createPatientPane(MediaSeriesGroup patient) { PatientPane pat = getPatientPane(patient); if (pat == null) { pat = new PatientPane(patient); patientPaneList.add(pat); } return pat; } private PatientPane getPatientPane(MediaSeriesGroup patient) { for (PatientPane p : patientPaneList) { if (p.isPatient(patient)) { return p; } } return null; } private StudyPane getStudyPane(MediaSeriesGroup study) { List<StudyPane> studies = patient2study.get(model.getParent(study, DicomModel.patient)); if (studies != null) { for (int i = 0; i < studies.size(); i++) { StudyPane st = studies.get(i); if (st.isStudy(study)) { return st; } } } return null; } private StudyPane createStudyPaneInstance(MediaSeriesGroup study, int[] position) { StudyPane studyPane = getStudyPane(study); if (studyPane == null) { studyPane = new StudyPane(study); List<StudyPane> studies = patient2study.get(model.getParent(study, DicomModel.patient)); if (studies != null) { int index = Collections.binarySearch(studies, studyPane, DicomSorter.STUDY_COMPARATOR); if (index < 0) { index = -(index + 1); } else { index = studies.size(); } if (position != null) { position[0] = index; } studies.add(index, studyPane); } } else if (position != null) { position[0] = -1; } return studyPane; } private void updateThumbnailSize() { int thumbnailSize = slider.getValue(); for (PatientPane p : patientContainer.getPatientPaneList()) { for (StudyPane studyPane : p.getStudyPaneList()) { for (SeriesPane series : studyPane.getSeriesPaneList()) { series.updateSize(thumbnailSize); } studyPane.doLayout(); } } patientContainer.revalidate(); patientContainer.repaint(); } private SeriesPane getSeriesPane(MediaSeriesGroup series) { List<SeriesPane> seriesList = study2series.get(model.getParent(series, DicomModel.study)); if (seriesList != null) { for (int j = 0; j < seriesList.size(); j++) { SeriesPane se = seriesList.get(j); if (se.isSeries(series)) { return se; } } } return null; } private synchronized SeriesPane createSeriesPaneInstance(MediaSeriesGroup series, int[] position) { SeriesPane seriesPane = getSeriesPane(series); if (seriesPane == null) { seriesPane = new SeriesPane(series); List<SeriesPane> seriesList = study2series.get(model.getParent(series, DicomModel.study)); if (seriesList != null) { int index = Collections.binarySearch(seriesList, seriesPane, DicomSorter.SERIES_COMPARATOR); if (index < 0) { index = -(index + 1); } else { index = seriesList.size(); } if (position != null) { position[0] = index; } seriesList.add(index, seriesPane); } } else if (position != null) { position[0] = -1; } return seriesPane; } private boolean isSelectedPatient(MediaSeriesGroup patient) { if (selectedPatient != null && selectedPatient.patient == patient) { return true; } return false; } class TitleBorder extends TitledBorder { public TitleBorder(String title) { super(title); setFont(FontTools.getFont10()); } @Override public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { // Measure the title length FontRenderContext frc = ((Graphics2D) g).getFontRenderContext(); Rectangle bound = getTitleFont().getStringBounds(title, frc).getBounds(); int panelLength = width - 15; if (bound.width > panelLength) { int length = (title.length() * panelLength) / bound.width; if (length > 2) { title = title.substring(0, length - 2) + "..."; //$NON-NLS-1$ } } super.paintBorder(c, g, x, y, width, height); } } @SuppressWarnings("serial") class PatientContainerPane extends JPanel { private final GridBagConstraints constraint = new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0); private final Component filler = Box.createRigidArea(new Dimension(5, 5)); public PatientContainerPane() { modelPatient.removeAllElements(); // do not use addElement // modelPatient.insertElementAt(ALL_PATIENTS, 0); setLayout(new GridBagLayout()); } List<PatientPane> getPatientPaneList() { List<PatientPane> patientPanes = new ArrayList<>(); for (Component c : this.getComponents()) { if (c instanceof PatientPane) { patientPanes.add((PatientPane) c); } } return patientPanes; } private void refreshLayout() { List<PatientPane> list = getPatientPaneList(); super.removeAll(); for (PatientPane p : list) { p.refreshLayout(); if (p.getComponentCount() > 0) { addPane(p); } } } private void showAllPatients() { super.removeAll(); for (PatientPane patientPane : patientPaneList) { patientPane.showTitle(true); patientPane.showAllstudies(); if (patientPane.getComponentCount() > 0) { addPane(patientPane); } } this.revalidate(); } public void addPane(PatientPane patientPane, int position) { constraint.gridx = verticalLayout ? 0 : position; constraint.gridy = verticalLayout ? position : 0; remove(filler); constraint.weightx = verticalLayout ? 1.0 : 0.0; constraint.weighty = verticalLayout ? 0.0 : 1.0; add(patientPane, constraint); constraint.weightx = verticalLayout ? 0.0 : 1.0; constraint.weighty = verticalLayout ? 1.0 : 0.0; add(filler, constraint); } public void addPane(PatientPane patientPane) { addPane(patientPane, GridBagConstraints.RELATIVE); } public boolean isPatientVisible(MediaSeriesGroup patient) { for (Component c : this.getComponents()) { if (c instanceof PatientPane) { if (((PatientPane) c).isPatient(patient)) { return true; } } } return false; } public boolean isStudyVisible(MediaSeriesGroup study) { MediaSeriesGroup patient = model.getParent(study, DicomModel.patient); for (Component c : this.getComponents()) { if (c instanceof PatientPane) { PatientPane patientPane = (PatientPane) c; if (patientPane.isPatient(patient) && patientPane.isStudyVisible(study)) { return true; } } } return false; } public boolean isSeriesVisible(MediaSeriesGroup series) { MediaSeriesGroup patient = model.getParent(series, DicomModel.patient); for (Component c : this.getComponents()) { if (c instanceof PatientPane) { PatientPane patientPane = (PatientPane) c; if (patientPane.isPatient(patient) && patientPane.isSeriesVisible(series)) { return true; } } } return false; } } @SuppressWarnings("serial") class PatientPane extends JPanel { private final MediaSeriesGroup patient; private final GridBagConstraints constraint = new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0); public PatientPane(MediaSeriesGroup patient) { if (patient == null) { throw new IllegalArgumentException("Patient cannot be null"); //$NON-NLS-1$ } this.patient = patient; this.setAlignmentX(LEFT_ALIGNMENT); this.setAlignmentY(TOP_ALIGNMENT); this.setFocusable(false); setLayout(new GridBagLayout()); } public void showTitle(boolean show) { if (show) { TitleBorder title = new TitleBorder(patient.toString()); title.setTitleFont(FontTools.getFont12Bold()); title.setTitleJustification(TitledBorder.LEFT); Color color = javax.swing.UIManager.getColor("ComboBox.buttonHighlight"); //$NON-NLS-1$ title.setTitleColor(color); title.setBorder(BorderFactory.createLineBorder(color, 2)); this.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, 5, 25, 5), title)); } else { this.setBorder(null); } } public boolean isStudyVisible(MediaSeriesGroup study) { for (Component c : this.getComponents()) { if (c instanceof StudyPane) { StudyPane studyPane = (StudyPane) c; if (studyPane.isStudy(study)) { return true; } } } return false; } public boolean isSeriesVisible(MediaSeriesGroup series) { MediaSeriesGroup study = model.getParent(series, DicomModel.study); for (Component c : this.getComponents()) { if (c instanceof StudyPane) { StudyPane studyPane = (StudyPane) c; if (studyPane.isStudy(study) && studyPane.isSeriesVisible(series)) { return true; } } } return false; } List<StudyPane> getStudyPaneList() { ArrayList<StudyPane> studyPaneList = new ArrayList<>(); for (Component c : this.getComponents()) { if (c instanceof StudyPane) { studyPaneList.add((StudyPane) c); } } return studyPaneList; } private void refreshLayout() { List<StudyPane> studies = getStudyPaneList(); super.removeAll(); for (StudyPane studyPane : studies) { studyPane.refreshLayout(); if (studyPane.getComponentCount() > 0) { addPane(studyPane); } studyPane.doLayout(); } this.revalidate(); } private void showAllstudies() { super.removeAll(); List<StudyPane> studies = patient2study.get(patient); if (studies != null) { for (StudyPane studyPane : studies) { studyPane.showAllSeries(); studyPane.refreshLayout(); if (studyPane.getComponentCount() > 0) { addPane(studyPane); } studyPane.doLayout(); } this.revalidate(); } } public void addPane(StudyPane studyPane) { addPane(studyPane, GridBagConstraints.RELATIVE); } public void addPane(StudyPane studyPane, int position) { constraint.gridx = verticalLayout ? 0 : position; constraint.gridy = verticalLayout ? position : 0; constraint.weightx = verticalLayout ? 1.0 : 0.0; constraint.weighty = 0.0; add(studyPane, constraint); } public boolean isPatient(MediaSeriesGroup patient) { return this.patient.equals(patient); } } @SuppressWarnings("serial") class StudyPane extends JPanel { final MediaSeriesGroup dicomStudy; private final TitleBorder title; public StudyPane(MediaSeriesGroup dicomStudy) { if (dicomStudy == null) { throw new IllegalArgumentException("Study cannot be null"); //$NON-NLS-1$ } this.setAlignmentX(LEFT_ALIGNMENT); this.setAlignmentY(TOP_ALIGNMENT); this.dicomStudy = dicomStudy; title = new TitleBorder(dicomStudy.toString()); title.setTitleFont(FontTools.getFont12()); title.setTitleJustification(TitledBorder.LEFT); this.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5), title)); this.setFocusable(false); refreshLayout(); } public boolean isSeriesVisible(MediaSeriesGroup series) { for (Component c : this.getComponents()) { if (c instanceof SeriesPane) { if (((SeriesPane) c).isSeries(series)) { return true; } } } return false; } List<SeriesPane> getSeriesPaneList() { ArrayList<SeriesPane> seriesPaneList = new ArrayList<>(); for (Component c : this.getComponents()) { if (c instanceof SeriesPane) { seriesPaneList.add((SeriesPane) c); } } return seriesPaneList; } private void refreshLayout() { this.setLayout(verticalLayout ? new WrapLayout(FlowLayout.LEFT) : new BoxLayout(this, BoxLayout.X_AXIS)); } private void showAllSeries() { super.removeAll(); List<SeriesPane> seriesList = study2series.get(dicomStudy); if (seriesList != null) { int thumbnailSize = slider.getValue(); for (int i = 0; i < seriesList.size(); i++) { SeriesPane series = seriesList.get(i); series.updateSize(thumbnailSize); addPane(series, i); } this.revalidate(); } } public void addPane(SeriesPane seriesPane, int index) { seriesPane.updateSize(slider.getValue()); add(seriesPane, index); updateText(); } public void updateText() { title.setTitle(dicomStudy.toString()); } public boolean isStudy(MediaSeriesGroup dicomStudy) { return this.dicomStudy.equals(dicomStudy); } } @SuppressWarnings("serial") class SeriesPane extends JPanel { final MediaSeriesGroup sequence; private final JLabel label; public SeriesPane(MediaSeriesGroup sequence) { this.sequence = Objects.requireNonNull(sequence); // To handle selection color with all L&Fs this.setUI(new javax.swing.plaf.PanelUI() { }); this.setOpaque(true); this.setBackground(JMVUtils.TREE_BACKROUND); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); int thumbnailSize = slider.getValue(); if (sequence instanceof Series) { Series series = (Series) sequence; Thumbnail thumb = (Thumbnail) series.getTagValue(TagW.Thumbnail); if (thumb == null) { thumb = createThumbnail(series, model, thumbnailSize); series.setTag(TagW.Thumbnail, thumb); } this.add(thumb); } this.setAlignmentX(LEFT_ALIGNMENT); this.setAlignmentY(TOP_ALIGNMENT); String desc = TagD.getTagValue(sequence, Tag.SeriesDescription, String.class); label = new JLabel(desc == null ? "" : desc, SwingConstants.CENTER); //$NON-NLS-1$ label.setFont(FontTools.getFont10()); label.setFocusable(false); this.setFocusable(false); updateSize(thumbnailSize); this.add(label); } public void updateSize(int thumbnailSize) { Dimension max = label.getMaximumSize(); if (max == null || max.width != thumbnailSize) { if (sequence instanceof Series) { Series series = (Series) sequence; SeriesThumbnail thumb = (SeriesThumbnail) series.getTagValue(TagW.Thumbnail); if (thumb != null) { thumb.setThumbnailSize(thumbnailSize); } } FontRenderContext frc = new FontRenderContext(null, false, false); Dimension dim = new Dimension(thumbnailSize, (int) (label.getFont().getStringBounds("0", frc).getHeight() + 1.0f)); //$NON-NLS-1$ label.setPreferredSize(dim); label.setMaximumSize(dim); } } public void updateText() { String desc = TagD.getTagValue(sequence, Tag.SeriesDescription, String.class); label.setText(desc == null ? "" : desc); //$NON-NLS-1$ } public boolean isSeries(MediaSeriesGroup sequence) { return this.sequence.equals(sequence); } public MediaSeriesGroup getSequence() { return sequence; } } /** * @return */ protected JPanel getMainPanel() { if (panelMain == null) { panelMain = new JPanel(); panel = new JPanel(); final GridBagLayout gridBagLayout = new GridBagLayout(); gridBagLayout.rowHeights = new int[] { 0, 0, 7 }; panel.setLayout(gridBagLayout); panel.setBorder(new EmptyBorder(5, 5, 5, 5)); final JLabel label = new JLabel(PATIENT_ICON); final GridBagConstraints gridBagConstraints = new GridBagConstraints(); gridBagConstraints.insets = new Insets(0, 0, 5, 5); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; panel.add(label, gridBagConstraints); final GridBagConstraints gridBagConstraints1 = new GridBagConstraints(); gridBagConstraints1.insets = new Insets(0, 2, 5, 0); gridBagConstraints1.anchor = GridBagConstraints.WEST; gridBagConstraints1.weightx = 1.0; gridBagConstraints1.gridy = 0; gridBagConstraints1.gridx = 1; panel.add(patientCombobox, gridBagConstraints1); patientCombobox.setMaximumRowCount(15); patientCombobox.setFont(FontTools.getFont11()); JMVUtils.setPreferredWidth(patientCombobox, 145, 145); // Update UI before adding the Tooltip feature in the combobox list patientCombobox.updateUI(); patientCombobox.addItemListener(patientChangeListener); JMVUtils.addTooltipToComboList(patientCombobox); final GridBagConstraints gridBagConstraints3 = new GridBagConstraints(); gridBagConstraints3.anchor = GridBagConstraints.WEST; gridBagConstraints3.insets = new Insets(2, 2, 5, 0); gridBagConstraints3.gridx = 1; gridBagConstraints3.gridy = 1; panel.add(studyCombobox, gridBagConstraints3); studyCombobox.setMaximumRowCount(15); studyCombobox.setFont(FontTools.getFont11()); // Update UI before adding the Tooltip feature in the combobox list studyCombobox.updateUI(); JMVUtils.setPreferredWidth(studyCombobox, 145, 145); // do not use addElement modelStudy.insertElementAt(ALL_STUDIES, 0); modelStudy.setSelectedItem(ALL_STUDIES); studyCombobox.addItemListener(studyItemListener); JMVUtils.addTooltipToComboList(studyCombobox); final GridBagConstraints gridBagConstraints4 = new GridBagConstraints(); gridBagConstraints4.anchor = GridBagConstraints.WEST; gridBagConstraints4.insets = new Insets(2, 2, 5, 0); gridBagConstraints4.gridx = 1; gridBagConstraints4.gridy = 2; panel.add(koOpen, gridBagConstraints4); koOpen.addActionListener(e -> { final MediaSeriesGroup patient = selectedPatient == null ? null : selectedPatient.patient; if (patient != null && e.getSource() instanceof JButton) { List<KOSpecialElement> list = DicomModel.getSpecialElements(patient, KOSpecialElement.class); if (list != null && !list.isEmpty()) { JButton button = (JButton) e.getSource(); if (list.size() == 1) { model.openrelatedSeries(list.get(0), patient); } else { Collections.sort(list, DicomSpecialElement.ORDER_BY_DATE); JPopupMenu popupMenu = new JPopupMenu(); popupMenu.add(new TitleMenuItem(ActionW.KO_SELECTION.getTitle(), popupMenu.getInsets())); popupMenu.addSeparator(); ButtonGroup group = new ButtonGroup(); for (final KOSpecialElement koSpecialElement : list) { final JMenuItem item = new JMenuItem(koSpecialElement.getShortLabel()); item.addActionListener(e1 -> model.openrelatedSeries(koSpecialElement, patient)); popupMenu.add(item); group.add(item); } popupMenu.show(button, 5, 5); } } } }); koOpen.setVisible(false); panelMain.setLayout(new BorderLayout()); panelMain.add(panel, BorderLayout.NORTH); JPanel panel2 = new JPanel(); if (BundleTools.SYSTEM_PREFERENCES.getBooleanProperty("weasis.explorer.moreoptions", true)) { //$NON-NLS-1$ GridBagConstraints gbcbtnMoreOptions = new GridBagConstraints(); gbcbtnMoreOptions.anchor = GridBagConstraints.EAST; gbcbtnMoreOptions.gridx = 1; gbcbtnMoreOptions.gridy = 3; btnMoreOptions.setFont(FontTools.getFont10()); btnMoreOptions.addActionListener(e -> { if (btnMoreOptions.isSelected()) { panelMain.add(panel2); } else { panelMain.remove(panel2); } panelMain.revalidate(); panelMain.repaint(); }); panel.add(btnMoreOptions, gbcbtnMoreOptions); } GridBagLayout gblpanel2 = new GridBagLayout(); panel2.setLayout(gblpanel2); JPanel panel3 = new JPanel(); GridBagConstraints gbcpanel3 = new GridBagConstraints(); gbcpanel3.weightx = 1.0; gbcpanel3.anchor = GridBagConstraints.NORTHWEST; gbcpanel3.gridx = 0; gbcpanel3.gridy = 0; FlowLayout flowLayout = (FlowLayout) panel3.getLayout(); flowLayout.setHgap(10); flowLayout.setAlignment(FlowLayout.LEFT); panel2.add(panel3, gbcpanel3); btnImport.setText(Messages.getString("DicomExplorer.import"));//$NON-NLS-1$ panel3.add(btnImport); btnExport.setText(Messages.getString("DicomExplorer.export"));//$NON-NLS-1$ panel3.add(btnExport); final JPanel palenSlider1 = new JPanel(); palenSlider1.setLayout(new BoxLayout(palenSlider1, BoxLayout.Y_AXIS)); palenSlider1 .setBorder(new TitledBorder(Messages.getString("DicomExplorer.thmb_size") + " " + slider.getValue())); //$NON-NLS-1$ //$NON-NLS-2$ slider.setPaintTicks(true); slider.setSnapToTicks(true); slider.setMajorTickSpacing(16); slider.addChangeListener(e -> { JSlider source = (JSlider) e.getSource(); if (!source.getValueIsAdjusting()) { ((TitledBorder) palenSlider1.getBorder()).setTitle(Messages.getString("DicomExplorer.thmb_size") //$NON-NLS-1$ + StringUtil.COLON_AND_SPACE + source.getValue()); palenSlider1.repaint(); updateThumbnailSize(); } }); JMVUtils.setPreferredWidth(slider, 145, 145); palenSlider1.add(slider); GridBagConstraints gbcpalenSlider1 = new GridBagConstraints(); gbcpalenSlider1.insets = new Insets(0, 5, 5, 5); gbcpalenSlider1.anchor = GridBagConstraints.NORTHWEST; gbcpalenSlider1.gridx = 0; gbcpalenSlider1.gridy = 1; panel2.add(palenSlider1, gbcpalenSlider1); } return panelMain; } public Set<Series> getSelectedPatientOpenSeries() { return getPatientOpenSeries(selectedPatient == null ? null :selectedPatient.patient); } public Set<Series> getPatientOpenSeries(MediaSeriesGroup patient) { Set<Series> openSeriesSet = new LinkedHashSet<>(); if (patient != null) { synchronized (model) { for (MediaSeriesGroup study : model.getChildren(patient)) { for (MediaSeriesGroup seq : model.getChildren(study)) { if (seq instanceof Series && Boolean.TRUE.equals(seq.getTagValue(TagW.SeriesOpen))) { openSeriesSet.add((Series) seq); } } } } } return openSeriesSet; } public boolean isPatientHasOpenSeries(MediaSeriesGroup patient) { synchronized (model) { for (MediaSeriesGroup study : model.getChildren(patient)) { for (MediaSeriesGroup seq : model.getChildren(study)) { if (seq instanceof Series) { Boolean open = (Boolean) ((Series) seq).getTagValue(TagW.SeriesOpen); return open == null ? false : open; } } } } return false; } public void selectPatient(MediaSeriesGroup patient) { if (selectedPatient == null || patient != selectedPatient.patient) { selectionList.clear(); studyCombobox.removeItemListener(studyItemListener); modelStudy.removeAllElements(); // do not use addElement modelStudy.insertElementAt(ALL_STUDIES, 0); modelStudy.setSelectedItem(ALL_STUDIES); patientContainer.removeAll(); if (patient == null) { selectedPatient = null; patientContainer.showAllPatients(); } else { selectedPatient = createPatientPane(patient); selectedPatient.showTitle(false); List<StudyPane> studies = patient2study.get(patient); if (studies != null) { for (StudyPane studyPane : studies) { modelStudy.addElement(studyPane.dicomStudy); } } studyCombobox.addItemListener(studyItemListener); selectStudy(); patientContainer.addPane(selectedPatient); koOpen.setVisible(DicomModel.hasSpecialElements(patient, KOSpecialElement.class)); // Send message for selecting related plug-ins window model.firePropertyChange(new ObservableEvent(ObservableEvent.BasicAction.SELECT, model, null, patient)); } } } private List<Series> getSplitSeries(Series dcm) { MediaSeriesGroup study = model.getParent(dcm, DicomModel.study); Object splitNb = dcm.getTagValue(TagW.SplitSeriesNumber); List<Series> list = new ArrayList<>(); if (splitNb == null || study == null) { list.add(dcm); return list; } String uid = TagD.getTagValue(dcm, Tag.SeriesInstanceUID, String.class); if (uid != null) { for (MediaSeriesGroup group : model.getChildren(study)) { if (group instanceof Series) { Series s = (Series) group; if (uid.equals(TagD.getTagValue(s, Tag.SeriesInstanceUID))) { list.add(s); } } } } return list; } private void updateSplitSeries(Series dcmSeries) { MediaSeriesGroup study = model.getParent(dcmSeries, DicomModel.study); // In case the Series has been replaced (split number = -1) and removed if (study == null) { return; } StudyPane studyPane = createStudyPaneInstance(study, null); List<Series> list = getSplitSeries(dcmSeries); List<SeriesPane> seriesList = study2series.get(study); if (seriesList == null) { seriesList = new ArrayList<>(); study2series.put(study, seriesList); } boolean addSeries = patientContainer.isStudyVisible(study); boolean repaintStudy = false; for (Series dicomSeries : list) { int[] positionSeries = new int[1]; createSeriesPaneInstance(dicomSeries, positionSeries); if (addSeries && positionSeries[0] != -1) { repaintStudy = true; } SeriesThumbnail thumb = (SeriesThumbnail) dicomSeries.getTagValue(TagW.Thumbnail); if (thumb != null) { thumb.reBuildThumbnail(); } } Integer nb = (Integer) dcmSeries.getTagValue(TagW.SplitSeriesNumber); // Convention -> split number inferior to 0 is a Series that has been replaced (ex. when a DicomSeries is // converted DicomVideoSeries after downloading files). if (nb != null && nb < 0) { model.removeSeries(dcmSeries); repaintStudy = true; } if (repaintStudy) { studyPane.removeAll(); for (int i = 0, k = 1; i < seriesList.size(); i++) { SeriesPane s = seriesList.get(i); studyPane.addPane(s, i); if (list.contains(s.getSequence())) { s.getSequence().setTag(TagW.SplitSeriesNumber, k); k++; } } studyPane.revalidate(); studyPane.repaint(); } else { int k = 1; for (SeriesPane s : seriesList) { if (list.contains(s.getSequence())) { s.getSequence().setTag(TagW.SplitSeriesNumber, k); k++; } } } } private void selectStudy() { Object item = modelStudy.getSelectedItem(); if (item instanceof MediaSeriesGroupNode) { MediaSeriesGroupNode selectedStudy = (MediaSeriesGroupNode) item; selectStudy(selectedStudy); } else { selectStudy(null); } } public void selectStudy(MediaSeriesGroup selectedStudy) { if (selectedPatient != null) { selectionList.clear(); selectedPatient.removeAll(); if (selectedStudy == null) { selectedPatient.showAllstudies(); } else { StudyPane studyPane = getStudyPane(selectedStudy); if (studyPane != null) { studyPane.showAllSeries(); studyPane.refreshLayout(); selectedPatient.addPane(studyPane); studyPane.doLayout(); } } selectedPatient.revalidate(); selectedPatient.repaint(); } } @Override public void dispose() { super.closeDockable(); } private void addDicomSeries(Series series) { if (DicomModel.isSpecialModality(series)) { // Up to now nothing has to be done in the explorer view about specialModality return; } LOGGER.info("Add series: {}", series); //$NON-NLS-1$ MediaSeriesGroup study = model.getParent(series, DicomModel.study); MediaSeriesGroup patient = model.getParent(series, DicomModel.patient); final PatientPane patientPane = createPatientPane(patient); if (modelPatient.getIndexOf(patient) < 0) { modelPatient.addElement(patient); if (modelPatient.getSize() == 1) { selectedPatient = patientPane; patientContainer.addPane(selectedPatient); patientCombobox.removeItemListener(patientChangeListener); patientCombobox.setSelectedItem(patient); patientCombobox.addItemListener(patientChangeListener); } // Mode all patients else if (selectedPatient == null) { patientContainer.addPane(patientPane); } } boolean addSeries = selectedPatient == patientPane; List<StudyPane> studies = patient2study.get(patient); if (studies == null) { studies = new ArrayList<>(); patient2study.put(patient, studies); } Object selectedStudy = modelStudy.getSelectedItem(); int[] positionStudy = new int[1]; StudyPane studyPane = createStudyPaneInstance(study, positionStudy); List<SeriesPane> seriesList = study2series.get(study); if (seriesList == null) { seriesList = new ArrayList<>(); study2series.put(study, seriesList); } int[] positionSeries = new int[1]; createSeriesPaneInstance(series, positionSeries); if (addSeries && positionSeries[0] != -1) { // If new study if (positionStudy[0] != -1) { if (modelStudy.getIndexOf(study) < 0) { modelStudy.addElement(study); } // if modelStudy has the value "All studies" if (ALL_STUDIES.equals(selectedStudy)) { patientPane.removeAll(); for (StudyPane s : studies) { patientPane.addPane(s); } patientPane.revalidate(); } } if (patientPane.isStudyVisible(study)) { studyPane.removeAll(); for (int i = 0; i < seriesList.size(); i++) { studyPane.addPane(seriesList.get(i), i); } studyPane.revalidate(); studyPane.repaint(); } } } @Override public void changingViewContentEvent(SeriesViewerEvent event) { EVENT type = event.getEventType(); if (EVENT.SELECT_VIEW.equals(type) && event.getSeriesViewer() instanceof ImageViewerPlugin) { ViewCanvas<?> pane = ((ImageViewerPlugin<?>) event.getSeriesViewer()).getSelectedImagePane(); if (pane != null) { MediaSeries s = pane.getSeries(); if (s != null) { if (!getSelectionList().isOpenningSeries() && patientContainer.isSeriesVisible(s)) { SeriesPane p = getSeriesPane(s); if (p != null) { JViewport vp = thumnailView.getViewport(); Rectangle bound = vp.getViewRect(); Point ptmin = SwingUtilities.convertPoint(p, new Point(0, 0), patientContainer); Point ptmax = SwingUtilities.convertPoint(p, new Point(0, p.getHeight()), patientContainer); if (!bound.contains(ptmin.x, ptmin.y) || !bound.contains(ptmax.x, ptmax.y)) { Point pt = vp.getViewPosition(); pt.y = ptmin.y + (ptmax.y - ptmin.y) / 2; pt.y -= vp.getHeight() / 2; int maxHeight = (int) (vp.getViewSize().getHeight() - vp.getExtentSize().getHeight()); if (pt.y < 0) { pt.y = 0; } else if (pt.y > maxHeight) { pt.y = maxHeight; } vp.setViewPosition(pt); // Clear the selection when another view is selected getSelectionList().clear(); } } } } } } } @Override public void propertyChange(PropertyChangeEvent evt) { // Get only event from the model of DicomExplorer if (evt instanceof ObservableEvent) { ObservableEvent event = (ObservableEvent) evt; ObservableEvent.BasicAction action = event.getActionCommand(); Object newVal = event.getNewValue(); if (model.equals(evt.getSource())) { if (ObservableEvent.BasicAction.SELECT.equals(action)) { if (newVal instanceof Series) { Series dcm = (Series) newVal; MediaSeriesGroup patient = model.getParent(dcm, DicomModel.patient); if (!isSelectedPatient(patient)) { modelPatient.setSelectedItem(patient); } } } else if (ObservableEvent.BasicAction.ADD.equals(action)) { if (newVal instanceof Series) { addDicomSeries((Series) newVal); } } else if (ObservableEvent.BasicAction.REMOVE.equals(action)) { if (newVal instanceof MediaSeriesGroup) { MediaSeriesGroup group = (MediaSeriesGroup) newVal; // Patient Group if (TagD.getUID(Level.PATIENT).equals(group.getTagID())) { removePatientPane(group); } // Study Group else if (TagD.getUID(Level.STUDY).equals(group.getTagID())) { removeStudy(group); } // Series Group else if (TagD.getUID(Level.SERIES).equals(group.getTagID())) { removeSeries(group); } } } // Update patient and study infos from the series (when receiving the first downloaded image) else if (ObservableEvent.BasicAction.UDPATE_PARENT.equals(action)) { if (newVal instanceof Series) { Series dcm = (Series) newVal; MediaSeriesGroup patient = model.getParent(dcm, DicomModel.patient); if (isSelectedPatient(patient)) { MediaSeriesGroup study = model.getParent(dcm, DicomModel.study); StudyPane studyPane = getStudyPane(study); if (studyPane != null) { if (!DicomModel.isSpecialModality(dcm)) { SeriesPane pane = getSeriesPane(dcm); if (pane != null) { pane.updateText(); } } studyPane.updateText(); } } } } // update else if (ObservableEvent.BasicAction.UPDATE.equals(action)) { if (newVal instanceof Series) { Series series = (Series) newVal; Integer splitNb = (Integer) series.getTagValue(TagW.SplitSeriesNumber); if (splitNb != null) { updateSplitSeries(series); } } else if (newVal instanceof MediaSeriesGroup && event.getOldValue() instanceof String) { MediaSeriesGroup patient = (MediaSeriesGroup) newVal; if (TagW.PatientPseudoUID.equals(patient.getTagID())) { // Fix hash of key when patientUID has changed MediaSeriesGroupNode oldPt = new MediaSeriesGroupNode(patient.getTagID(), event.getOldValue(), null) { @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof MediaSeriesGroup)) return false; // According to the implementation of MediaSeriesGroupNode, the identifier cannot be null return Objects.equals(patient.getTagValue(getTagID()), ((MediaSeriesGroup) obj).getTagValue(getTagID())); } }; patient2study.put(patient, patient2study.remove(oldPt)); } } else if (newVal instanceof KOSpecialElement) { Object item = modelPatient.getSelectedItem(); if (item instanceof MediaSeriesGroupNode) { koOpen.setVisible( DicomModel.hasSpecialElements((MediaSeriesGroup) item, KOSpecialElement.class)); } } } else if (ObservableEvent.BasicAction.LOADING_START.equals(action)) { if (newVal instanceof ExplorerTask) { addTaskToGlobalProgression((ExplorerTask<?, ?>) newVal); } } else if (ObservableEvent.BasicAction.LOADING_STOP.equals(action) || ObservableEvent.BasicAction.LOADING_CANCEL.equals(action)) { if (newVal instanceof ExplorerTask) { removeTaskToGlobalProgression((ExplorerTask<?, ?>) newVal); } } } else if (evt.getSource() instanceof SeriesViewer) { if (ObservableEvent.BasicAction.SELECT.equals(action)) { if (newVal instanceof MediaSeriesGroup) { MediaSeriesGroup patient = (MediaSeriesGroup) newVal; if (!isSelectedPatient(patient)) { modelPatient.setSelectedItem(patient); // focus get back to viewer if (evt.getSource() instanceof ViewerPlugin) { ((ViewerPlugin) evt.getSource()).requestFocusInWindow(); } } } } } } } @Override public String getDescription() { return DESCRIPTION; } @Override public Icon getIcon() { // TODO Auto-generated method stub return null; } @Override public String getUIName() { return NAME; } @Override public String toString() { return NAME; } @Override public DataExplorerModel getDataExplorerModel() { return model; } @Override protected void changeToolWindowAnchor(CLocation clocation) { removeAll(); add(getMainPanel(), verticalLayout ? BorderLayout.NORTH : BorderLayout.WEST); patientContainer.refreshLayout(); add(thumnailView, BorderLayout.CENTER); add(loadingPanel, verticalLayout ? BorderLayout.SOUTH : BorderLayout.EAST); } public synchronized void addTaskToGlobalProgression(final ExplorerTask task) { GuiExecutor.instance().invokeAndWait(() -> { loadingPanel.addTask(task); revalidate(); repaint(); }); } public synchronized void removeTaskToGlobalProgression(final ExplorerTask task) { GuiExecutor.instance().invokeAndWait(() -> { if (loadingPanel.removeTask(task)) { revalidate(); repaint(); } }); } public static SeriesThumbnail createThumbnail(final Series series, final DicomModel dicomModel, final int thumbnailSize) { Callable<SeriesThumbnail> callable = () -> { final SeriesThumbnail thumb = new SeriesThumbnail(series, thumbnailSize); if (series.getSeriesLoader() instanceof LoadSeries) { // In case series is downloaded or canceled LoadSeries loader = (LoadSeries) series.getSeriesLoader(); thumb.setProgressBar(loader.isDone() ? null : loader.getProgressBar()); } thumb.registerListeners(); ThumbnailMouseAndKeyAdapter thumbAdapter = new ThumbnailMouseAndKeyAdapter(series, dicomModel, null); thumb.addMouseListener(thumbAdapter); thumb.addKeyListener(thumbAdapter); return thumb; }; FutureTask<SeriesThumbnail> future = new FutureTask<>(callable); GuiExecutor.instance().invokeAndWait(future); SeriesThumbnail result = null; try { result = future.get(); } catch (InterruptedException | ExecutionException e) { LOGGER.error("Building Series thumbnail", e); //$NON-NLS-1$ } return result; } @Override public void importFiles(File[] files, boolean recursive) { if (files != null) { DicomModel.LOADING_EXECUTOR.execute(new LoadLocalDicom(files, recursive, model)); } } @Override public List<Action> getOpenExportDialogAction() { return Arrays.asList(btnExport.getAction()); } @Override public List<Action> getOpenImportDialogAction() { ArrayList<Action> actions = new ArrayList<>(2); actions.add(btnImport.getAction()); DefaultAction importCDAction = new DefaultAction(Messages.getString("DicomExplorer.dcmCD"), //$NON-NLS-1$ new ImageIcon(DicomExplorer.class.getResource("/icon/16x16/cd.png")), //$NON-NLS-1$ event -> openImportDialogAction(Messages.getString("DicomExplorer.dcmCD"))); //$NON-NLS-1$ actions.add(importCDAction); return actions; } private void openImportDialogAction(String actionName) { File file = DicomDirImport.getDcmDirFromMedia(); if (file == null) { int response = JOptionPane.showConfirmDialog(SwingUtilities.getWindowAncestor(this), "Cannot find DICOMDIR on media device, do you want to import manually?", //$NON-NLS-1$ actionName, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); if (response == JOptionPane.YES_OPTION) { ColorLayerUI layer = ColorLayerUI.createTransparentLayerUI(this); DicomImport dialog = new DicomImport(SwingUtilities.getWindowAncestor(this), model); dialog.showPage(Messages.getString("DicomDirImport.dicomdir")); //$NON-NLS-1$ ColorLayerUI.showCenterScreen(dialog, layer); } } else { List<LoadSeries> loadSeries = DicomDirImport.loadDicomDir(file, model, true); if (loadSeries != null && !loadSeries.isEmpty()) { DicomModel.LOADING_EXECUTOR.execute(new LoadDicomDir(loadSeries, model)); } else { LOGGER.error("Cannot import DICOM from {}", file); //$NON-NLS-1$ int response = JOptionPane.showConfirmDialog(SwingUtilities.getWindowAncestor(this), Messages.getString("DicomExplorer.mes_import_manual"), //$NON-NLS-1$ actionName, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); if (response == JOptionPane.YES_OPTION) { ColorLayerUI layer = ColorLayerUI.createTransparentLayerUI(this); DicomImport dialog = new DicomImport(SwingUtilities.getWindowAncestor(this), model); dialog.showPage(Messages.getString("LocalImport.local_dev")); //$NON-NLS-1$ AbstractItemDialogPage page = dialog.getCurrentPage(); if (page instanceof LocalImport) { ((LocalImport) page).setImportPath(file.getParent()); } ColorLayerUI.showCenterScreen(dialog, layer); } } } } @Override public boolean canImportFiles() { return true; } }