	public void initGUI() {
		cardsModeltable = new MagicCardTableModel();
		JPanel panelResultsCards;
		JPanel panelFilters;
		JPanel panelmana;
		JPanel editionDetailPanel;
		JPanel panneauHaut;
		JPanel panneauCard;
		JPanel panneauStat;
		JTextField txtFilter;
		JButton btnClear;
		JButton btnFilter;

		DefaultRowSorter<TableModel, Integer> sorterCards;
		sorterCards = new TableRowSorter<>(cardsModeltable);
		sorterCards.setComparator(7, new NumberSorter());

		List<MTGEdition> li = new ArrayList<>();
		try {
			li = getEnabledPlugin(MTGCardsProvider.class).listEditions();
			Collections.sort(li);
		} catch (Exception e2) {
			logger.error("error no edition loaded", e2);
		}

		//////// INIT COMPONENTS

		var scrollThumbnails = new JScrollPane();
		var panneauCentral = new JSplitPane();
		iaPanel = new IASuggestionPanel();
		panneauStat = new JPanel();
		panneauHaut = new JPanel();
		panneauCard = new JPanel();
		editionDetailPanel = new JPanel();
		panelResultsCards = new JPanel();
		abilitiesPanel = new CardAbilitiesPanel();
		cmcChart = new CmcChartPanel();
		gedPanel = new GedPanel<>();
		manaRepartitionPanel = new ManaRepartitionPanel(false);
		typeRepartitionPanel = new TypeRepartitionPanel(false);
		stockPanel = new CardStockPanel();
		historyChartPanel = new HistoryPricesPanel(true);
		cardsPicPanel = new ImagePanel();
		priceTablePanel = new PricesTablePanel();
		rarityRepartitionPanel = new RarityRepartitionPanel(false);
		detailCardPanel = new MagicCardDetailPanel(true);
		panelmana = new JPanel();
		panelFilters = new JPanel();
		var pan = new ManaPanel();
		panelJson = new ObjectViewerPanel();
		tabbedCardsView = new JTabbedPane(SwingConstants.TOP);
		thumbnailPanel = new HandPanel();
		thumbnailPanel.setBackground(MTGConstants.THUMBNAIL_BACKGROUND_COLOR);
		btnExport = new JExportButton(MODS.EXPORT);
		UITools.bindJButton(btnExport, KeyEvent.VK_E, "Search Export");
		btnFilter = UITools.createBindableJButton(null, MTGConstants.ICON_FILTER, KeyEvent.VK_F, "searchfilter");
		btnClear = UITools.createBindableJButton(null, MTGConstants.ICON_CLEAR, KeyEvent.VK_C, "clear");
		similarityPanel = new SimilarityCardPanel();
		tableCards = UITools.createNewTable(cardsModeltable);
		lblLoading = AbstractBuzyIndicatorComponent.createProgressComponent();
		var lblFilter = new JLabel();
		listEdition = new JList<>();
		var advancedSearch = UITools.createBindableJButton(null, MTGConstants.ICON_SEARCH_ADVANCED, KeyEvent.VK_A, "AdvancedSearch");
		searchComponent = new CriteriaComponent(false);
		defaultEnterButton = new JButton(MTGConstants.ICON_SEARCH);
		txtRulesArea = new RulesPanel();

		txtFilter = new JTextField();

		UITools.initTableFilter(tableCards);

		deckPanel = new CardsDeckCheckerPanel();

		//////// MODELS
		listEdition.setModel(new DefaultListModel<>());

		//////// RENDERER
		tableCards.getColumnModel().getColumn(2).setCellRenderer(new ManaCellRenderer());
		tableCards.getColumnModel().getColumn(6).setCellRenderer(new MagicEditionsJLabelRenderer());
		listEdition.setCellRenderer(new MagicEditionIconListRenderer());

		///////// CONFIGURE COMPONENTS

		btnFilter.setToolTipText(capitalize("FILTER"));
		btnExport.setToolTipText(capitalize("EXPORT_RESULTS"));
		btnExport.setEnabled(false);
		listEdition.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		thumbnailPanel.enableDragging(false);
		panneauCentral.setOrientation(JSplitPane.VERTICAL_SPLIT);
		panneauCentral.setRightComponent(getContextTabbedPane());
		panneauCentral.setLeftComponent(tabbedCardsView);

		tableCards.setRowSorter(sorterCards);

		for(int i : cardsModeltable.defaultHiddenColumns())
			tableCards.getColumnExt(cardsModeltable.getColumnName(i)).setVisible(false);

		panneauCentral.setDividerLocation(0.5);
		panneauCentral.setResizeWeight(0.5);

		/////// LAYOUT
		setLayout(new BorderLayout());
		panneauStat.setLayout(new GridLayout(2, 2, 0, 0));
		panneauCard.setLayout(new BorderLayout());
		editionDetailPanel.setLayout(new BorderLayout());
		panelResultsCards.setLayout(new BorderLayout(0, 0));
		panelmana.setLayout(new GridLayout(1, 0, 2, 2));

		var flpanelFilters = (FlowLayout) panelFilters.getLayout();
		flpanelFilters.setAlignment(FlowLayout.LEFT);

		var flowLayout = (FlowLayout) panneauHaut.getLayout();
		flowLayout.setAlignment(FlowLayout.LEFT);

		/////// DIMENSION
		thumbnailPanel.setThumbnailSize(new Dimension(179, 240));
		cardsPicPanel.setPreferredSize(new Dimension(500, 10));

		scrollThumbnails.getVerticalScrollBar().setUnitIncrement(10);
		txtFilter.setColumns(25);

		/////// VISIBILITY
		tableCards.setColumnControlVisible(true);
		panelFilters.setVisible(false);
		lblLoading.setVisible(false);
		tableCards.setShowVerticalLines(false);

		////// ADD PANELS
		for (String s : new String[] { "W", "U", "B", "R", "G", "C", "1" }) {
			final var btnG = new JButton();
			btnG.setToolTipText(s);
			if (s.equals("1"))
				btnG.setToolTipText("[0-9]*");

			btnG.setIcon(new ImageIcon(pan.getManaSymbol(s).getScaledInstance(15, 15, Image.SCALE_SMOOTH)));
			btnG.setForeground(btnG.getBackground());
			btnG.addActionListener(e -> {
				txtFilter.setText("\\{" + btnG.getToolTipText() + "}");
				sorterCards.setRowFilter(RowFilter.regexFilter(txtFilter.getText()));
			});
			panelmana.add(btnG);

		}
		scrollThumbnails.setViewportView(thumbnailPanel);
		thumbnailPanel.setEnclosingScrollPane(scrollThumbnails);

		panneauHaut.add(searchComponent);
		panneauHaut.add(advancedSearch);
		panneauHaut.add(btnFilter);
		panneauHaut.add(btnExport);
		panneauHaut.add(lblLoading);
		panneauCard.add(new JScrollPane(listEdition), BorderLayout.SOUTH);
		panneauCard.add(cardsPicPanel, BorderLayout.CENTER);

		panelResultsCards.add(panelFilters, BorderLayout.NORTH);
		panelResultsCards.add(new JScrollPane(tableCards),BorderLayout.CENTER);
		magicEditionDetailPanel = new MagicEditionDetailPanel();

		editionDetailPanel.add(magicEditionDetailPanel, BorderLayout.CENTER);

		panelFilters.add(lblFilter);
		panelFilters.add(txtFilter);
		panelFilters.add(btnClear);
		panelFilters.add(panelmana);

		addContextComponent(detailCardPanel);
		addContextComponent(new JScrollPane(editionDetailPanel),"EDITION",MTGConstants.ICON_TAB_BACK);
		addContextComponent(priceTablePanel);
		addContextComponent(txtRulesArea);
		addContextComponent(historyChartPanel);
		addContextComponent(similarityPanel);
		addContextComponent(deckPanel);
		addContextComponent(stockPanel);
		addContextComponent(abilitiesPanel);
		addContextComponent(gedPanel);
		addContextComponent(iaPanel);
		if(MTG.readPropertyAsBoolean("debug-json-panel"))
			addContextComponent(panelJson);

		panneauStat.add(cmcChart);
		panneauStat.add(manaRepartitionPanel);
		panneauStat.add(typeRepartitionPanel);
		panneauStat.add(rarityRepartitionPanel);

		tabbedCardsView.addTab(capitalize("RESULTS"),  MTGConstants.ICON_TAB_RESULTS,panelResultsCards, null);
		tabbedCardsView.addTab(capitalize("THUMBNAIL"), MTGConstants.ICON_TAB_THUMBNAIL,scrollThumbnails, null);
		tabbedCardsView.addTab(capitalize("STATS"), MTGConstants.ICON_TAB_ANALYSE, panneauStat,null);

		add(panneauHaut, BorderLayout.NORTH);
		add(panneauCard, BorderLayout.EAST);
		add(panneauCentral, BorderLayout.CENTER);

		/////// Right click
		try {
			initPopupCollection();
		} catch (Exception e2) {
			logger.error("error init popup",e2);
		}

		/////// Action listners
		addComponentListener(new ComponentAdapter() {
			@Override
		    public void componentShown(ComponentEvent componentEvent){
		        searchComponent.requestFocus();
				panneauCentral.setDividerLocation(.45);
				removeComponentListener(this);
		    }
		});

		similarityPanel.getTableSimilarity().addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent evt) {

				if(similarityPanel.getTableSimilarity().getSelectedRow()==-1)
					return;

				MTGCard mc = UITools.getTableSelection(similarityPanel.getTableSimilarity(), 0);
				cardsPicPanel.init(mc);
			}
		});

		advancedSearch.addActionListener(il->{
			var diag = new AdvancedSearchQueryDialog();
									  diag.setVisible(true);

			if(diag.getCrits().isEmpty())
				return;

			lblLoading.start();
			lblLoading.setText(capitalize("SEARCHING"));
			cardsModeltable.clear();

			var wk = new AbstractObservableWorker<List<MTGCard>, MTGCard, MTGCardsProvider>(lblLoading,getEnabledPlugin(MTGCardsProvider.class)) {

						@Override
						protected List<MTGCard> doInBackground() throws Exception {

							if(diag.getCollection()==null)
							{
								return plug.searchByCriteria(diag.getCrits());
							}
							else
							{
								return plug.searchByCriteria(diag.getCrits()).stream().filter(mc->{
									try {
										return MTG.getEnabledPlugin(MTGDao.class).listCollectionFromCards(mc).contains(diag.getCollection());
									} catch (SQLException e) {
										logger.error("error sql for {} : {}",mc,e);
										return false;
									}
								}).toList();
							}
						}

						@Override
						protected void process(List<MTGCard> chunks) {
							super.process(chunks);
							cardsModeltable.addItems(chunks);
						}

						@Override
						protected void done() {
							super.done();
							open(getResult());
							btnExport.setEnabled(tableCards.getRowCount() > 0);
						}

			};

			ThreadManager.getInstance().runInEdt(wk,"searching "+diag.getCrits());

		});

		btnClear.addActionListener(ae -> {
			txtFilter.setText("");
			sorterCards.setRowFilter(null);
		});

		btnFilter.addActionListener(ae -> panelFilters.setVisible(!panelFilters.isVisible()));

		searchComponent.addButton(defaultEnterButton,true);

		defaultEnterButton.addActionListener(el->{
					selectedEdition = null;
					lblLoading.start();
					lblLoading.setText(capitalize("SEARCHING"));

					MTGPlugin plug = searchComponent.isCollectionSearch() ? getEnabledPlugin(MTGDao.class):getEnabledPlugin(MTGCardsProvider.class);
					cardsModeltable.clear();

					AbstractObservableWorker<List<MTGCard>, MTGCard, MTGPlugin> wk = new AbstractObservableWorker<>(lblLoading,plug) {
						@Override
						protected List<MTGCard> doInBackground() throws Exception {
							List<MTGCard> cards;

							if (searchComponent.isCollectionSearch()) {
								cards=((MTGDao)plug).listCardsFromCollection((MTGCollection) searchComponent.getMTGCriteria().getFirst());
							}
							else if(searchComponent.isSetSearch()) {
								cards=((MTGCardsProvider)plug).searchCardByEdition((MTGEdition)searchComponent.getMTGCriteria().getFirst());
							}
							else if (searchComponent.isAllCardsSearch()) {
								cards=((MTGCardsProvider)plug).listAllCards();

							}
							else {
								cards=((MTGCardsProvider)plug).searchCardByCriteria(searchComponent.getMTGCriteria().getAtt(), ((MTGCardsProvider)plug).getMTGQueryManager().getValueFor(searchComponent.getMTGCriteria().getFirst()).toString(), null, false);
							}

							try {
								Collections.sort(cards, new CardsEditionSorter());
							}
							catch(Exception e)
							{
								logger.error("error sorting result",e);
							}

							return cards;
						}

						@Override
						protected void process(List<MTGCard> chunks) {
							super.process(chunks);
							cardsModeltable.addItems(chunks);
						}

						@Override
						protected void done() {
							super.done();
							open(getResult());
							btnExport.setEnabled(tableCards.getRowCount() > 0);
						}
					};
					ThreadManager.getInstance().runInEdt(wk,"searching "+searchComponent.getMTGCriteria());
		});

		tableCards.getSelectionModel().addListSelectionListener(event -> {
			if (!event.getValueIsAdjusting()) {
				try {
					selectedCard = UITools.getTableSelection(tableCards, 0);

					if(selectedCard==null)
						return;

					selectedEdition = selectedCard.getEdition();
					updateCards();
				} catch (Exception e) {
					logger.error("error selecting line",e);
				}
			}
		});

		tableCards.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent evt) {
				if(tableCards.getSelectedRow()==-1)
					return;

				if (SwingUtilities.isRightMouseButton(evt)) {
					var point = evt.getPoint();
					popupMenu.show(tableCards, (int) point.getX(), (int) point.getY());
				} else {
					try {
						selectedCard = UITools.getTableSelection(tableCards, 0);
						selectedEdition = selectedCard.getEdition();
						updateCards();
					} catch (Exception e) {
						logger.error(e);
					}

				}
			}
		});

		listEdition.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent mev) {
				selectedEdition = listEdition.getSelectedValue();

				if(selectedEdition==null)
					return;

				SwingWorker<MTGCard, MTGCard> sw = new SwingWorker<>()
						{

							@Override
							protected void process(List<MTGCard> chunks) {
								detailCardPanel.init(chunks.get(0));
								magicEditionDetailPanel.init(selectedEdition);
							}

							@Override
							protected MTGCard doInBackground() throws Exception {
								try {

									MTGCard mc = CardsManagerService.switchEditions(selectedCard, selectedEdition);
									publish(mc);
									return mc;
								} catch (Exception e) {
									logger.error(e);
									return null;
								}

							}
							@Override
							protected void done() {
								try {
									selectedCard = get();
									cardsPicPanel.init(selectedCard); // backcard
									historyChartPanel.init(selectedCard, selectedEdition, selectedCard.getName());
									priceTablePanel.init(selectedCard);
								}catch(InterruptedException ex)
								{
									Thread.currentThread().interrupt();
								}
								catch (Exception e) {
									logger.error(e);
								}
							}

						};

				ThreadManager.getInstance().runInEdt(sw,"loading " + selectedCard);
			}
		});

		btnExport.initCardsExport(new Callable<MTGDeck>() {
			@Override
			public MTGDeck call() throws Exception {
				List<MTGCard> export = UITools.getTableSelections(tableCards,0);

				if(export.isEmpty())
					export =  ((MagicCardTableModel) tableCards.getRowSorter().getModel()).getItems();

				return MTGDeck.toDeck(export);
			}
		}, lblLoading);

		txtFilter.addActionListener(ae -> {
			String text = txtFilter.getText();
			if (text.length() == 0) {
				sorterCards.setRowFilter(null);
			} else {
				sorterCards.setRowFilter(RowFilter.regexFilter(text));
			}
		});

		thumbnailPanel.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				var lab = (DisplayableCard) thumbnailPanel.getComponentAt(new Point(e.getX(), e.getY()));
				selectedCard = lab.getMagicCard();
				selectedEdition = lab.getMagicCard().getEdition();
				cardsPicPanel.init(selectedCard);
				updateCards();
			}

		});
	}

	public void initGUI() {
		cardsModeltable = new MagicCardTableModel();
		JPanel panelResultsCards;
		JPanel panelFilters;
		JPanel panelmana;
		JPanel editionDetailPanel;
		JPanel panneauHaut;
		JPanel panneauCard;
		JPanel panneauStat;
		JTextField txtFilter;
		JButton btnClear;
		JButton btnFilter;

		DefaultRowSorter<TableModel, Integer> sorterCards;
		sorterCards = new TableRowSorter<>(cardsModeltable);
		sorterCards.setComparator(7, new NumberSorter());

		List<MTGEdition> li = new ArrayList<>();
		try {
			li = getEnabledPlugin(MTGCardsProvider.class).listEditions();
			Collections.sort(li);
		} catch (Exception e2) {
			logger.error("error no edition loaded", e2);
		}

		//////// INIT COMPONENTS

		var scrollThumbnails = new JScrollPane();
		var panneauCentral = new JSplitPane();
		iaPanel = new IASuggestionPanel();
		panneauStat = new JPanel();
		panneauHaut = new JPanel();
		panneauCard = new JPanel();
		editionDetailPanel = new JPanel();
		panelResultsCards = new JPanel();
		abilitiesPanel = new CardAbilitiesPanel();
		cmcChart = new CmcChartPanel();
		gedPanel = new GedPanel<>();
		manaRepartitionPanel = new ManaRepartitionPanel(false);
		typeRepartitionPanel = new TypeRepartitionPanel(false);
		stockPanel = new CardStockPanel();
		historyChartPanel = new HistoryPricesPanel(true);
		cardsPicPanel = new ImagePanel();
		priceTablePanel = new PricesTablePanel();
		rarityRepartitionPanel = new RarityRepartitionPanel(false);
		detailCardPanel = new MagicCardDetailPanel(true);
		panelmana = new JPanel();
		panelFilters = new JPanel();
		var pan = new ManaPanel();
		panelJson = new ObjectViewerPanel();
		tabbedCardsView = new JTabbedPane(SwingConstants.TOP);
		thumbnailPanel = new HandPanel();
		thumbnailPanel.setBackground(MTGConstants.THUMBNAIL_BACKGROUND_COLOR);
		btnExport = new JExportButton(MODS.EXPORT);
		UITools.bindJButton(btnExport, KeyEvent.VK_E, "Search Export");
		btnFilter = UITools.createBindableJButton(null, MTGConstants.ICON_FILTER, KeyEvent.VK_F, "searchfilter");
		btnClear = UITools.createBindableJButton(null, MTGConstants.ICON_CLEAR, KeyEvent.VK_C, "clear");
		similarityPanel = new SimilarityCardPanel();
		tableCards = UITools.createNewTable(cardsModeltable);
		lblLoading = AbstractBuzyIndicatorComponent.createProgressComponent();
		var lblFilter = new JLabel();
		listEdition = new JList<>();
		var advancedSearch = UITools.createBindableJButton(null, MTGConstants.ICON_SEARCH_ADVANCED, KeyEvent.VK_A, "AdvancedSearch");
		searchComponent = new CriteriaComponent(false);
		defaultEnterButton = new JButton(MTGConstants.ICON_SEARCH);
		txtRulesArea = new RulesPanel();

		txtFilter = new JTextField();

		UITools.initTableFilter(tableCards);

		deckPanel = new CardsDeckCheckerPanel();

		//////// MODELS
		listEdition.setModel(new DefaultListModel<>());

		//////// RENDERER
		tableCards.getColumnModel().getColumn(2).setCellRenderer(new ManaCellRenderer());
		tableCards.getColumnModel().getColumn(6).setCellRenderer(new MagicEditionsJLabelRenderer());
		listEdition.setCellRenderer(new MagicEditionIconListRenderer());

		///////// CONFIGURE COMPONENTS

		btnFilter.setToolTipText(capitalize("FILTER"));
		btnExport.setToolTipText(capitalize("EXPORT_RESULTS"));
		btnExport.setEnabled(false);
		listEdition.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		thumbnailPanel.enableDragging(false);
		panneauCentral.setOrientation(JSplitPane.VERTICAL_SPLIT);
		panneauCentral.setRightComponent(getContextTabbedPane());
		panneauCentral.setLeftComponent(tabbedCardsView);

		tableCards.setRowSorter(sorterCards);

		for(int i : cardsModeltable.defaultHiddenColumns())
			tableCards.getColumnExt(cardsModeltable.getColumnName(i)).setVisible(false);

		panneauCentral.setDividerLocation(0.5);
		panneauCentral.setResizeWeight(0.5);

		/////// LAYOUT
		setLayout(new BorderLayout());
		panneauStat.setLayout(new GridLayout(2, 2, 0, 0));
		panneauCard.setLayout(new BorderLayout());
		editionDetailPanel.setLayout(new BorderLayout());
		panelResultsCards.setLayout(new BorderLayout(0, 0));
		panelmana.setLayout(new GridLayout(1, 0, 2, 2));

		var flpanelFilters = (FlowLayout) panelFilters.getLayout();
		flpanelFilters.setAlignment(FlowLayout.LEFT);

		var flowLayout = (FlowLayout) panneauHaut.getLayout();
		flowLayout.setAlignment(FlowLayout.LEFT);

		/////// DIMENSION
		thumbnailPanel.setThumbnailSize(new Dimension(179, 240));
		cardsPicPanel.setPreferredSize(new Dimension(500, 10));

		scrollThumbnails.getVerticalScrollBar().setUnitIncrement(10);
		txtFilter.setColumns(25);

		/////// VISIBILITY
		tableCards.setColumnControlVisible(true);
		panelFilters.setVisible(false);
		lblLoading.setVisible(false);
		tableCards.setShowVerticalLines(false);

		////// ADD PANELS
		for (String s : new String[] { "W", "U", "B", "R", "G", "C", "1" }) {
			final var btnG = new JButton();
			btnG.setToolTipText(s);
			if (s.equals("1"))
				btnG.setToolTipText("[0-9]*");

			btnG.setIcon(new ImageIcon(pan.getManaSymbol(s).getScaledInstance(15, 15, Image.SCALE_SMOOTH)));
			btnG.setForeground(btnG.getBackground());
			btnG.addActionListener(e -> {
				txtFilter.setText("\\{" + btnG.getToolTipText() + "}");
				sorterCards.setRowFilter(RowFilter.regexFilter(txtFilter.getText()));
			});
			panelmana.add(btnG);

		}
		scrollThumbnails.setViewportView(thumbnailPanel);
		thumbnailPanel.setEnclosingScrollPane(scrollThumbnails);

		panneauHaut.add(searchComponent);
		panneauHaut.add(advancedSearch);
		panneauHaut.add(btnFilter);
		panneauHaut.add(btnExport);
		panneauHaut.add(lblLoading);
		panneauCard.add(new JScrollPane(listEdition), BorderLayout.SOUTH);
		panneauCard.add(cardsPicPanel, BorderLayout.CENTER);

		panelResultsCards.add(panelFilters, BorderLayout.NORTH);
		panelResultsCards.add(new JScrollPane(tableCards),BorderLayout.CENTER);
		magicEditionDetailPanel = new MagicEditionDetailPanel();

		editionDetailPanel.add(magicEditionDetailPanel, BorderLayout.CENTER);

		panelFilters.add(lblFilter);
		panelFilters.add(txtFilter);
		panelFilters.add(btnClear);
		panelFilters.add(panelmana);

		addContextComponent(detailCardPanel);
		addContextComponent(new JScrollPane(editionDetailPanel),"EDITION",MTGConstants.ICON_TAB_BACK);
		addContextComponent(priceTablePanel);
		addContextComponent(txtRulesArea);
		addContextComponent(historyChartPanel);
		addContextComponent(similarityPanel);
		addContextComponent(deckPanel);
		addContextComponent(stockPanel);
		addContextComponent(abilitiesPanel);
		addContextComponent(gedPanel);
		addContextComponent(iaPanel);
		if(MTG.readPropertyAsBoolean("debug-json-panel"))
			addContextComponent(panelJson);

		panneauStat.add(cmcChart);
		panneauStat.add(manaRepartitionPanel);
		panneauStat.add(typeRepartitionPanel);
		panneauStat.add(rarityRepartitionPanel);

		tabbedCardsView.addTab(capitalize("RESULTS"),  MTGConstants.ICON_TAB_RESULTS,panelResultsCards, null);
		tabbedCardsView.addTab(capitalize("THUMBNAIL"), MTGConstants.ICON_TAB_THUMBNAIL,scrollThumbnails, null);
		tabbedCardsView.addTab(capitalize("STATS"), MTGConstants.ICON_TAB_ANALYSE, panneauStat,null);

		add(panneauHaut, BorderLayout.NORTH);
		add(panneauCard, BorderLayout.EAST);
		add(panneauCentral, BorderLayout.CENTER);

		/////// Right click
		try {
			initPopupCollection();
		} catch (Exception e2) {
			logger.error("error init popup",e2);
		}

		/////// Action listners
		addComponentListener(new ComponentAdapter() {
			@Override
		    public void componentShown(ComponentEvent componentEvent){
		        searchComponent.requestFocus();
				panneauCentral.setDividerLocation(.45);
				removeComponentListener(this);
		    }
		});

		similarityPanel.getTableSimilarity().addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent evt) {

				if(similarityPanel.getTableSimilarity().getSelectedRow()==-1)
					return;

				MTGCard mc = UITools.getTableSelection(similarityPanel.getTableSimilarity(), 0);
				cardsPicPanel.init(mc);
			}
		});

		advancedSearch.addActionListener(il->{
			var diag = new AdvancedSearchQueryDialog();
									  diag.setVisible(true);

			if(diag.getCrits().isEmpty())
				return;

			lblLoading.start();
			lblLoading.setText(capitalize("SEARCHING"));
			cardsModeltable.clear();

			var wk = new AbstractObservableWorker<List<MTGCard>, MTGCard, MTGCardsProvider>(lblLoading,getEnabledPlugin(MTGCardsProvider.class)) {

						@Override
						protected List<MTGCard> doInBackground() throws Exception {

							if(diag.getCollection()==null)
							{
								return plug.searchByCriteria(diag.getCrits());
							}
							else
							{
								return plug.searchByCriteria(diag.getCrits()).stream().filter(mc->{
									try {
										return MTG.getEnabledPlugin(MTGDao.class).listCollectionFromCards(mc).contains(diag.getCollection());
									} catch (SQLException e) {
										logger.error("error sql for {} : {}",mc,e);
										return false;
									}
								}).toList();
							}
						}

						@Override
						protected void process(List<MTGCard> chunks) {
							super.process(chunks);
							cardsModeltable.addItems(chunks);
						}

						@Override
						protected void done() {
							super.done();
							open(getResult());
							btnExport.setEnabled(tableCards.getRowCount() > 0);
						}

			};

			ThreadManager.getInstance().runInEdt(wk,"searching "+diag.getCrits());

		});

		btnClear.addActionListener(ae -> {
			txtFilter.setText("");
			sorterCards.setRowFilter(null);
		});

		btnFilter.addActionListener(ae -> panelFilters.setVisible(!panelFilters.isVisible()));

		searchComponent.addButton(defaultEnterButton,true);

		defaultEnterButton.addActionListener(el->{
					selectedEdition = null;
					lblLoading.start();
					lblLoading.setText(capitalize("SEARCHING"));

					MTGPlugin plug = searchComponent.isCollectionSearch() ? getEnabledPlugin(MTGDao.class):getEnabledPlugin(MTGCardsProvider.class);
					cardsModeltable.clear();

					AbstractObservableWorker<List<MTGCard>, MTGCard, MTGPlugin> wk = new AbstractObservableWorker<>(lblLoading,plug) {
						@Override
						protected List<MTGCard> doInBackground() throws Exception {
							List<MTGCard> cards;

							if (searchComponent.isCollectionSearch()) {
								cards=((MTGDao)plug).listCardsFromCollection((MTGCollection) searchComponent.getMTGCriteria().getFirst());
							}
							else if(searchComponent.isSetSearch()) {
								cards=((MTGCardsProvider)plug).searchCardByEdition((MTGEdition)searchComponent.getMTGCriteria().getFirst());
							}
							else if (searchComponent.isAllCardsSearch()) {
								cards=((MTGCardsProvider)plug).listAllCards();

							}
							else {
								cards=((MTGCardsProvider)plug).searchCardByCriteria(searchComponent.getMTGCriteria().getAtt(), ((MTGCardsProvider)plug).getMTGQueryManager().getValueFor(searchComponent.getMTGCriteria().getFirst()).toString(), null, false);
							}

							try {
								Collections.sort(cards, new CardsEditionSorter());
							}
							catch(Exception e)
							{
								logger.error("error sorting result",e);
							}

							return cards;
						}

						@Override
						protected void process(List<MTGCard> chunks) {
							super.process(chunks);
							cardsModeltable.addItems(chunks);
						}

						@Override
						protected void done() {
							super.done();
							open(getResult());
							btnExport.setEnabled(tableCards.getRowCount() > 0);
						}
					};
					ThreadManager.getInstance().runInEdt(wk,"searching "+searchComponent.getMTGCriteria());
		});

		tableCards.getSelectionModel().addListSelectionListener(event -> {
			if (!event.getValueIsAdjusting()) {
				try {
					selectedCard = UITools.getTableSelection(tableCards, 0);

					if(selectedCard==null)
						return;

					selectedEdition = selectedCard.getCurrentSet();
					updateCards();
				} catch (Exception e) {
					logger.error("error selecting line",e);
				}
			}
		});

		tableCards.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent evt) {
				if(tableCards.getSelectedRow()==-1)
					return;

				if (SwingUtilities.isRightMouseButton(evt)) {
					var point = evt.getPoint();
					popupMenu.show(tableCards, (int) point.getX(), (int) point.getY());
				} else {
					try {
						selectedCard = UITools.getTableSelection(tableCards, 0);
						selectedEdition = selectedCard.getCurrentSet();
						updateCards();
					} catch (Exception e) {
						logger.error(e);
					}

				}
			}
		});

		listEdition.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent mev) {
				selectedEdition = listEdition.getSelectedValue();

				if(selectedEdition==null)
					return;

				SwingWorker<MTGCard, MTGCard> sw = new SwingWorker<>()
						{

							@Override
							protected void process(List<MTGCard> chunks) {
								detailCardPanel.init(chunks.get(0));
								magicEditionDetailPanel.init(selectedEdition);
							}

							@Override
							protected MTGCard doInBackground() throws Exception {
								try {

									MTGCard mc = CardsManagerService.switchEditions(selectedCard, selectedEdition);
									publish(mc);
									return mc;
								} catch (Exception e) {
									logger.error(e);
									return null;
								}

							}
							@Override
							protected void done() {
								try {
									selectedCard = get();
									cardsPicPanel.init(selectedCard); // backcard
									historyChartPanel.init(selectedCard, selectedEdition, selectedCard.getName());
									priceTablePanel.init(selectedCard);
								}catch(InterruptedException ex)
								{
									Thread.currentThread().interrupt();
								}
								catch (Exception e) {
									logger.error(e);
								}
							}

						};

				ThreadManager.getInstance().runInEdt(sw,"loading " + selectedCard);
			}
		});

		btnExport.initCardsExport(new Callable<MTGDeck>() {
			@Override
			public MTGDeck call() throws Exception {
				List<MTGCard> export = UITools.getTableSelections(tableCards,0);

				if(export.isEmpty())
					export =  ((MagicCardTableModel) tableCards.getRowSorter().getModel()).getItems();

				return MTGDeck.toDeck(export);
			}
		}, lblLoading);

		txtFilter.addActionListener(ae -> {
			String text = txtFilter.getText();
			if (text.length() == 0) {
				sorterCards.setRowFilter(null);
			} else {
				sorterCards.setRowFilter(RowFilter.regexFilter(text));
			}
		});

		thumbnailPanel.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				var lab = (DisplayableCard) thumbnailPanel.getComponentAt(new Point(e.getX(), e.getY()));
				selectedCard = lab.getMagicCard();
				selectedEdition = lab.getMagicCard().getCurrentSet();
				cardsPicPanel.init(selectedCard);
				updateCards();
			}

		});
	}

Replace Anonymous With Lambda org.magic.gui.components.card.CardSearchPanel.initGUI.addMouseListener.new MouseAdapter with event -> {if(!event.getValueIsAdjusting()){tryselectedCard=UITools.getTableSelection(tableCards,0); in method public initGUI() : void from class org.magic.gui.components.card.CardSearchPanel


	private static void runThreadFor(ActiveMQNetworkClient client) {
		new Thread(()->{
				try {
				//	client.sendMessage("Coucou de "+client.getPlayer(),Color.red);

					while(client.isActive())
						System.out.println(client.getPlayer() +" receive"+  URLTools.toJson(client.consume()).getAsJsonObject().get("message").getAsString());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}).start();

	}

	private static void runThreadFor(ActiveMQNetworkClient client) {
		new Thread(new Runnable() {

			@Override
			public void run() {
				try {
				//	client.sendMessage("Coucou de "+client.getPlayer(),Color.red);

					while(client.isActive())
						System.out.println(client.getPlayer() +" receive"+  URLTools.toJson(client.consume()).getAsJsonObject().get("message").getAsString());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		}).start();

	}

Replace Anonymous With Lambda org.beta.TestConsumers.runThreadFor.start.new Thread.new Runnable with () -> {trywhile(client.isActive())System.out.println(client.getPlayer() + " receive" + URLTools.toJson(client.consume()).getAsJsonObject().get("message").getAsString()); in method private runThreadFor(client ActiveMQNetworkClient) : void from class org.beta.TestConsumers


	protected void add(DescContainer dc) {
		dataList.computeIfAbsent(dc.getSetCode(), v->new ArrayList<>()).add(dc);

	}

	protected void add(DescContainer dc) {
		dataList.computeIfAbsent(dc.getSetCode(), v->new ArrayList<DescContainer>()).add(dc);

	}

Replace Generic With Diamond ArrayList<DescContainer> with ArrayList<> in method protected add(dc DescContainer) : void from class org.magic.api.interfaces.abstracts.AbstractRecognitionStrategy


	private void initGUI() {

		model = new SealedStockTableModel();
		var objectpanel = new ObjectViewerPanel();
		table = UITools.createNewTable(model);
		UITools.setDefaultRenderer(table, new StockTableRenderer());
		UITools.initTableFilter(table);
		packagePanel = new PackagesBrowserPanel(false);
		GedPanel<SealedStock> gedPanel = new GedPanel<>();
		buzy = AbstractBuzyIndicatorComponent.createProgressComponent();
		textEditor = new RSyntaxTextArea();
		textEditor.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_HTML);
		textEditor.setWrapStyleWord(true);
		textEditor.setLineWrap(true);
		textEditor.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				if(selectedStock!=null)
				{
					selectedStock.setComment(textEditor.getText());
					selectedStock.setUpdated(true);
				}
			}
		});
		var synchroPanel = new StockItemsSynchronizationPanel();
		var toolsPanel = new JPanel();
		var centerPanel = new JSplitPane();
		centerPanel.setOrientation(JSplitPane.VERTICAL_SPLIT);
		centerPanel.setDividerLocation(0.5);
		centerPanel.setResizeWeight(0.5);
		var panneauDetail = new JTabbedPane();
		var historyPricePanel= new SealedHistoryPricesPanel();
		var buttonNew = UITools.createBindableJButton(null, MTGConstants.ICON_NEW, KeyEvent.VK_N, "stock new");
		var buttonDelete = UITools.createBindableJButton(null, MTGConstants.ICON_DELETE, KeyEvent.VK_N, "stock delete");
		buttonDelete.setEnabled(false);
		buttonNew.setEnabled(false);

		var buttonUpdate = UITools.createBindableJButton(null, MTGConstants.ICON_REFRESH, KeyEvent.VK_U, "stock refresh");
		var buttonSave= UITools.createBindableJButton(null, MTGConstants.ICON_SAVE, KeyEvent.VK_S, "stock save");

		setLayout(new BorderLayout());

		toolsPanel.add(buttonNew);
		toolsPanel.add(buttonDelete);
		toolsPanel.add(buttonUpdate);
		toolsPanel.add(buttonSave);
		toolsPanel.add(buzy);

		panneauDetail.addTab(capitalize("INFO"),MTGConstants.ICON_TAB_PICTURE,packagePanel.getThumbnailPanel());
		UITools.addTab(panneauDetail, historyPricePanel);
		UITools.addTab(panneauDetail, gedPanel);
		UITools.addTab(panneauDetail, MTGUIComponent.build(new JScrollPane(textEditor), "description", MTGConstants.ICON_MANUAL));
		UITools.addTab(panneauDetail,synchroPanel);

		if (MTGControler.getInstance().get("debug-json-panel").equalsIgnoreCase("true"))
			UITools.addTab(panneauDetail, objectpanel);

		add(packagePanel,BorderLayout.WEST);
		centerPanel.setLeftComponent(new JScrollPane(table));
		centerPanel.setRightComponent(panneauDetail);
		add(centerPanel,BorderLayout.CENTER);
		add(toolsPanel,BorderLayout.NORTH);

		model.setWritable(true);

		packagePanel.getTree().addTreeSelectionListener(e-> {

			DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)packagePanel.getTree().getLastSelectedPathComponent();

			if(selectedNode==null || selectedNode.getUserObject()==null)
				return;

			boolean isPackage = selectedNode.getUserObject() instanceof MTGSealedProduct;
			buttonNew.setEnabled(isPackage);

			if(selectedNode!=null && isPackage)
			{

				selectedItem = (MTGSealedProduct)selectedNode.getUserObject();
				historyPricePanel.init(selectedItem, selectedItem.getEdition()+"-"+selectedItem.getTypeProduct());
				objectpanel.show(selectedItem);
			}
		});

		table.getSelectionModel().addListSelectionListener(l->{

			if(!l.getValueIsAdjusting())
			{
				selectedStock = UITools.getTableSelection(table, 0);

				buttonDelete.setEnabled(selectedStock!=null);

				if(selectedStock!=null)
				{

					historyPricePanel.init(selectedStock.getProduct(), selectedStock.getProduct().getEdition()+"-"+ selectedStock.getProduct().getTypeProduct());
					packagePanel.load(selectedStock.getProduct());
					synchroPanel.init(selectedStock);
					objectpanel.show(selectedStock);
					gedPanel.init(SealedStock.class, selectedStock);
					textEditor.setText(selectedStock.getComment());
				}
			}
		});

		buttonDelete.addActionListener(el->{
			List<SealedStock> list = UITools.getTableSelections(table, 0);

			int res = JOptionPane.showConfirmDialog(null, MTGControler.getInstance().getLangService().get("CONFIRM_DELETE", list.size()), MTGControler.getInstance().getLangService().get("DELETE"),JOptionPane.YES_NO_OPTION);

			if(res==JOptionPane.YES_OPTION)
			{
				AbstractObservableWorker<Void, SealedStock, MTGDao> sw = new AbstractObservableWorker<>(buzy,getEnabledPlugin(MTGDao.class),1) {

					@Override
					protected Void doInBackground() throws Exception {
						for(SealedStock ss : list)
							plug.deleteStock(ss);

						return null;
					}

					@Override
					protected void notifyEnd()
					{
						try {
							model.init(getEnabledPlugin(MTGDao.class).listSealedStocks());
						} catch (SQLException e) {
							logger.error(e);
						}
					}

				};

				ThreadManager.getInstance().runInEdt(sw, "delete" + list.size()+ "stocks Sealed");
			}

		});

		buttonUpdate.addActionListener(el->{
			try {
				model.init(getEnabledPlugin(MTGDao.class).listSealedStocks());
			} catch (SQLException e1) {
				MTGControler.getInstance().notify(e1);
			}

		});

		buttonNew.addActionListener(el->{
				AbstractObservableWorker<SealedStock, SealedStock, MTGDao> sw = new AbstractObservableWorker<>(buzy,getEnabledPlugin(MTGDao.class),1) {

					@Override
					protected SealedStock doInBackground() throws Exception {
						var s = new SealedStock(selectedItem);
						s.setQte(1);
						plug.saveOrUpdateSealedStock(s);
						return s;
					}

					@Override
					protected void notifyEnd()
					{
						try {
							model.addItem(get());
						} catch (InterruptedException | ExecutionException e) {
							Thread.currentThread().interrupt();
						}
					}

				};

				ThreadManager.getInstance().runInEdt(sw, "Saving stocks Sealed");
		});

		buttonSave.addActionListener(el->{
				var list = model.getItems().stream().filter(SealedStock::isUpdated).toList();

				AbstractObservableWorker<Void, SealedStock, MTGDao> sw = new AbstractObservableWorker<>(buzy,getEnabledPlugin(MTGDao.class),list.size()) {
					@Override
					protected Void doInBackground() throws Exception {
						for(SealedStock ss : list)
							plug.saveOrUpdateSealedStock(ss);

						return null;
					}
				};

				ThreadManager.getInstance().runInEdt(sw, "Saving stocks Sealed");

		});

	}

	private void initGUI() {

		model = new SealedStockTableModel();
		var objectpanel = new ObjectViewerPanel();
		table = UITools.createNewTable(model);
		UITools.setDefaultRenderer(table, new StockTableRenderer());
		UITools.initTableFilter(table);
		packagePanel = new PackagesBrowserPanel(false);
		GedPanel<SealedStock> gedPanel = new GedPanel<>();
		buzy = AbstractBuzyIndicatorComponent.createProgressComponent();
		textEditor = new RSyntaxTextArea();
		textEditor.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_HTML);
		textEditor.setWrapStyleWord(true);
		textEditor.setLineWrap(true);
		textEditor.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				if(selectedStock!=null)
				{
					selectedStock.setComment(textEditor.getText());
					selectedStock.setUpdated(true);
				}
			}
		});
		var synchroPanel = new StockItemsSynchronizationPanel();
		var toolsPanel = new JPanel();
		var centerPanel = new JSplitPane();
		centerPanel.setOrientation(JSplitPane.VERTICAL_SPLIT);
		centerPanel.setDividerLocation(0.5);
		centerPanel.setResizeWeight(0.5);
		var panneauDetail = new JTabbedPane();
		var historyPricePanel= new SealedHistoryPricesPanel();
		var buttonNew = UITools.createBindableJButton(null, MTGConstants.ICON_NEW, KeyEvent.VK_N, "stock new");
		var buttonDelete = UITools.createBindableJButton(null, MTGConstants.ICON_DELETE, KeyEvent.VK_N, "stock delete");
		buttonDelete.setEnabled(false);
		buttonNew.setEnabled(false);

		var buttonUpdate = UITools.createBindableJButton(null, MTGConstants.ICON_REFRESH, KeyEvent.VK_U, "stock refresh");
		var buttonSave= UITools.createBindableJButton(null, MTGConstants.ICON_SAVE, KeyEvent.VK_S, "stock save");

		setLayout(new BorderLayout());

		toolsPanel.add(buttonNew);
		toolsPanel.add(buttonDelete);
		toolsPanel.add(buttonUpdate);
		toolsPanel.add(buttonSave);
		toolsPanel.add(buzy);

		panneauDetail.addTab(capitalize("INFO"),MTGConstants.ICON_TAB_PICTURE,packagePanel.getThumbnailPanel());
		UITools.addTab(panneauDetail, historyPricePanel);
		UITools.addTab(panneauDetail, gedPanel);
		UITools.addTab(panneauDetail, MTGUIComponent.build(new JScrollPane(textEditor), "description", MTGConstants.ICON_MANUAL));
		UITools.addTab(panneauDetail,synchroPanel);

		if (MTGControler.getInstance().get("debug-json-panel").equalsIgnoreCase("true"))
			UITools.addTab(panneauDetail, objectpanel);

		add(packagePanel,BorderLayout.WEST);
		centerPanel.setLeftComponent(new JScrollPane(table));
		centerPanel.setRightComponent(panneauDetail);
		add(centerPanel,BorderLayout.CENTER);
		add(toolsPanel,BorderLayout.NORTH);

		model.setWritable(true);

		packagePanel.getTree().addTreeSelectionListener(e-> {

			DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)packagePanel.getTree().getLastSelectedPathComponent();

			if(selectedNode==null || selectedNode.getUserObject()==null)
				return;

			boolean isPackage = selectedNode.getUserObject() instanceof MTGSealedProduct;
			buttonNew.setEnabled(isPackage);

			if(selectedNode!=null && isPackage)
			{

				selectedItem = (MTGSealedProduct)selectedNode.getUserObject();
				historyPricePanel.init(selectedItem, selectedItem.getEdition()+"-"+selectedItem.getTypeProduct());
				objectpanel.show(selectedItem);
			}
		});

		table.getSelectionModel().addListSelectionListener(l->{

			if(!l.getValueIsAdjusting())
			{
				selectedStock = UITools.getTableSelection(table, 0);

				buttonDelete.setEnabled(selectedStock!=null);

				if(selectedStock!=null)
				{

					historyPricePanel.init(selectedStock.getProduct(), selectedStock.getProduct().getEdition()+"-"+ selectedStock.getProduct().getTypeProduct());
					packagePanel.load(selectedStock.getProduct());
					synchroPanel.init(selectedStock);
					objectpanel.show(selectedStock);
					gedPanel.init(SealedStock.class, selectedStock);
					textEditor.setText(selectedStock.getComment());
				}
			}
		});

		buttonDelete.addActionListener(el->{
			List<SealedStock> list = UITools.getTableSelections(table, 0);

			int res = JOptionPane.showConfirmDialog(null, MTGControler.getInstance().getLangService().get("CONFIRM_DELETE", list.size()), MTGControler.getInstance().getLangService().get("DELETE"),JOptionPane.YES_NO_OPTION);

			if(res==JOptionPane.YES_OPTION)
			{
				AbstractObservableWorker<Void, SealedStock, MTGDao> sw = new AbstractObservableWorker<Void, SealedStock, MTGDao>(buzy,getEnabledPlugin(MTGDao.class),1) {

					@Override
					protected Void doInBackground() throws Exception {
						for(SealedStock ss : list)
							plug.deleteStock(ss);

						return null;
					}

					@Override
					protected void notifyEnd()
					{
						try {
							model.init(getEnabledPlugin(MTGDao.class).listSealedStocks());
						} catch (SQLException e) {
							logger.error(e);
						}
					}

				};

				ThreadManager.getInstance().runInEdt(sw, "delete" + list.size()+ "stocks Sealed");
			}

		});

		buttonUpdate.addActionListener(el->{
			try {
				model.init(getEnabledPlugin(MTGDao.class).listSealedStocks());
			} catch (SQLException e1) {
				MTGControler.getInstance().notify(e1);
			}

		});

		buttonNew.addActionListener(el->{
				AbstractObservableWorker<SealedStock, SealedStock, MTGDao> sw = new AbstractObservableWorker<SealedStock, SealedStock, MTGDao>(buzy,getEnabledPlugin(MTGDao.class),1) {

					@Override
					protected SealedStock doInBackground() throws Exception {
						var s = new SealedStock(selectedItem);
						s.setQte(1);
						plug.saveOrUpdateSealedStock(s);
						return s;
					}

					@Override
					protected void notifyEnd()
					{
						try {
							model.addItem(get());
						} catch (InterruptedException | ExecutionException e) {
							Thread.currentThread().interrupt();
						}
					}

				};

				ThreadManager.getInstance().runInEdt(sw, "Saving stocks Sealed");
		});

		buttonSave.addActionListener(el->{
				var list = model.getItems().stream().filter(SealedStock::isUpdated).toList();

				AbstractObservableWorker<Void, SealedStock, MTGDao> sw = new AbstractObservableWorker<Void, SealedStock, MTGDao>(buzy,getEnabledPlugin(MTGDao.class),list.size()) {
					@Override
					protected Void doInBackground() throws Exception {
						for(SealedStock ss : list)
							plug.saveOrUpdateSealedStock(ss);

						return null;
					}
				};

				ThreadManager.getInstance().runInEdt(sw, "Saving stocks Sealed");

		});

	}

Replace Generic With Diamond AbstractObservableWorker<Void,SealedStock,MTGDao> with AbstractObservableWorker<> in method private initGUI() : void from class org.magic.gui.SealedStockGUI


	@Override
	public void onFirstShowing() {
			AbstractObservableWorker<List<SealedStock>, SealedStock, MTGDao> sw2 = new AbstractObservableWorker<>(buzy,getEnabledPlugin(MTGDao.class)) {

			@Override
			protected List<SealedStock> doInBackground() throws Exception {
				return plug.listSealedStocks();
			}

			@Override
			protected void done() {
				super.done();
				try {
					model.init(get());
				} catch (InterruptedException| ExecutionException e) {
					Thread.currentThread().interrupt();
				}
				table.packAll();

			}
		};

		SwingWorker<Void, Void> sw  = new SwingWorker<>(){
			@Override
			protected Void doInBackground() throws Exception {
				packagePanel.initTree();
				return null;
			}
			@Override
			protected void done() {
				packagePanel.reload();
				ThreadManager.getInstance().runInEdt(sw2, "Loading sealedstock");
			}
		};

		ThreadManager.getInstance().runInEdt(sw, "Loading sealed tree");

	}

	@Override
	public void onFirstShowing() {
			AbstractObservableWorker<List<SealedStock>, SealedStock, MTGDao> sw2 = new AbstractObservableWorker<List<SealedStock>, SealedStock, MTGDao>(buzy,getEnabledPlugin(MTGDao.class)) {

			@Override
			protected List<SealedStock> doInBackground() throws Exception {
				return plug.listSealedStocks();
			}

			@Override
			protected void done() {
				super.done();
				try {
					model.init(get());
				} catch (InterruptedException| ExecutionException e) {
					Thread.currentThread().interrupt();
				}
				table.packAll();

			}
		};

		SwingWorker<Void, Void> sw  = new SwingWorker<>(){
			@Override
			protected Void doInBackground() throws Exception {
				packagePanel.initTree();
				return null;
			}
			@Override
			protected void done() {
				packagePanel.reload();
				ThreadManager.getInstance().runInEdt(sw2, "Loading sealedstock");
			}
		};

		ThreadManager.getInstance().runInEdt(sw, "Loading sealed tree");

	}

Replace Generic With Diamond AbstractObservableWorker<List<SealedStock>,SealedStock,MTGDao> with AbstractObservableWorker<> in method public onFirstShowing() : void from class org.magic.gui.SealedStockGUI


					@Override
					protected void process(List<File> chunks)
					{
						buzy.progressSmooth(chunks.size());
						for(File f :chunks) {
							try {
								var entry = new GedEntry<>(FileTools.readFileAsBinary(f),classe, instance.getStoreId(),f.getName());
								MTG.getEnabledPlugin(MTGGedStorage.class).store(entry);
								addEntry(entry);
							} catch (IOException e) {
								logger.error(e);
							}
						}
					}

					@Override
					protected void process(List<File> chunks)
					{
						buzy.progressSmooth(chunks.size());
						for(File f :chunks) {
							try {
								var entry = new GedEntry<T>(FileTools.readFileAsBinary(f),classe, instance.getStoreId(),f.getName());
								MTG.getEnabledPlugin(MTGGedStorage.class).store(entry);
								addEntry(entry);
							} catch (IOException e) {
								logger.error(e);
							}
						}
					}

Replace Generic With Diamond GedEntry<T> with GedEntry<> in method protected process(chunks List<File>) : void from class org.magic.gui.components.GedPanel.GedPanel.addActionListener.sw.new SwingWorker<>


	public TechnicalMonitorPanel() {
		setLayout(new BorderLayout(0, 0));
		modelThreads = new ThreadsTableModel();
		modelTasks = new TaskTableModel();
		modelNetwork = new NetworkTableModel();
		queryModel = new QueriesTableModel();
		modelConfig = new MapTableModel<>();
		modelDao = new MapTableModel<>();
		modelCacheJson = new MapTableModel<>();
		modelJsonServerInfo = new JsonInfoTableModel();
		discordModel = new DiscordInfoTableModel();
		gedPanel = new GedBrowserPanel();

		modelScript = new GenericTableModel<>()
				{
					private static final long serialVersionUID = 1L;
					@Override
					public Object getValueAt(int row, int column) {
						return items.get(row).get(getColumnName(column));
					}

					@Override
					public String getColumnName(int column) {
						return columns[column];
					}
				};

		var tabs = new JTabbedPane();
		add(tabs, BorderLayout.CENTER);

		modelTasks.bind(TechnicalServiceManager.inst().getTasksInfos());
		modelNetwork.bind(TechnicalServiceManager.inst().getNetworkInfos());
		queryModel.bind(TechnicalServiceManager.inst().getDaoInfos());
		modelJsonServerInfo.bind(TechnicalServiceManager.inst().getJsonInfo());
		discordModel.bind(TechnicalServiceManager.inst().getDiscordInfos());
		modelConfig.init(TechnicalServiceManager.inst().getSystemInfo());
		modelDao.init(MTG.getEnabledPlugin(MTGDao.class).getDBSize());

		var tableTasks = UITools.createNewTable(modelTasks);
		UITools.initTableFilter(tableTasks);

		var tableNetwork = UITools.createNewTable(modelNetwork);
		UITools.initTableFilter(tableNetwork);

		var tableScripts = UITools.createNewTable(modelScript);
		UITools.initTableFilter(tableScripts);

		var tableQueries = UITools.createNewTable(queryModel);
		UITools.initTableFilter(tableQueries);

		var tableDaos = UITools.createNewTable(modelDao);
		UITools.initTableFilter(tableDaos);

		var tableCacheJson = UITools.createNewTable(modelCacheJson);
		UITools.initTableFilter(tableCacheJson);

		var tableJsonInfo= UITools.createNewTable(modelJsonServerInfo);
		UITools.initTableFilter(tableJsonInfo);

		var tableDiscordInfo= UITools.createNewTable(discordModel);
		UITools.initTableFilter(tableDiscordInfo);

		TableCellRenderer durationRenderer = (JTable table, Object value, boolean isSelected,boolean hasFocus, int row, int column)->{

						var lab= new JLabel(DurationFormatUtils.formatDurationHMS((Long)value));
						lab.setOpaque(false);
						return lab;
				};

		TableCellRenderer sizeRenderer = (JTable table, Object value, boolean isSelected,boolean hasFocus, int row, int column)->{
					var lab= new JLabel(UITools.humanReadableSize((Long)value));
					lab.setOpaque(false);
					return lab;
			};

		tableTasks.setDefaultRenderer(Long.class, durationRenderer);
		tableNetwork.setDefaultRenderer(Long.class, durationRenderer);
		tableQueries.setDefaultRenderer(Long.class, durationRenderer);
		tableDaos.setDefaultRenderer(Long.class, sizeRenderer);
		tableJsonInfo.setDefaultRenderer(Long.class, durationRenderer);
		tableDiscordInfo.setDefaultRenderer(Long.class, durationRenderer);

		tabs.addTab("Config",MTGConstants.ICON_SMALL_HELP,new JScrollPane(UITools.createNewTable(modelConfig)));
		tabs.addTab("Threads",MTGConstants.ICON_TAB_ADMIN,new JScrollPane(UITools.createNewTable(modelThreads)));
		tabs.addTab("Tasks",MTGConstants.ICON_TAB_ADMIN,new JScrollPane(tableTasks));
		tabs.addTab("Network",MTGConstants.ICON_TAB_NETWORK,new JScrollPane(tableNetwork));
		tabs.addTab("Qwartz Script",MTGConstants.ICON_SMALL_SCRIPT,new JScrollPane(tableScripts));
		tabs.addTab("Queries",MTGConstants.ICON_TAB_DAO,new JScrollPane(tableQueries));
		tabs.addTab("DB Size",MTGConstants.ICON_TAB_DAO,new JScrollPane(tableDaos));
		tabs.addTab("Discord",ImageTools.resize(new DiscordBotServer().getIcon(),15,15)  ,new JScrollPane(tableDiscordInfo));
		tabs.addTab("JsonServer Cache",MTGConstants.ICON_TAB_CACHE,new JScrollPane(tableCacheJson));
		tabs.addTab("JsonServer Queries",MTGConstants.ICON_TAB_SERVER,new JScrollPane(tableJsonInfo));
		UITools.addTab(tabs, new LoggerViewPanel());
		UITools.addTab(tabs, gedPanel);

		var panel = new JPanel();
		add(panel, BorderLayout.NORTH);

		memoryPanel = new JVMemoryPanel();
		panel.add(memoryPanel);

		t = new Timer(5000, e ->{
			modelThreads.init(TechnicalServiceManager.inst().getThreadsInfos());
			memoryPanel.refresh();
			modelTasks.fireTableDataChanged();
			modelNetwork.fireTableDataChanged();
			modelConfig.fireTableDataChanged();
			queryModel.fireTableDataChanged();
			modelDao.fireTableDataChanged();
			modelJsonServerInfo.fireTableDataChanged();
			discordModel.fireTableDataChanged();

			if(MTG.getPlugin("Qwartz", MTGServer.class).isAlive()) {
				try {
					modelScript.bind( ((QwartzServer)MTG.getPlugin("Qwartz", MTGServer.class)).getJobs()  );
					modelScript.setColumns(modelScript.getItems().get(0).keySet().stream().toArray(String[]::new));
					modelScript.fireTableStructureChanged();
					modelScript.fireTableDataChanged();

				}
				catch(Exception ex)
				{
					logger.error("error loading . Maybe Qwartz server is stopped",ex);
				}
			}

			if(MTG.getPlugin("Json Http Server", MTGServer.class).isAlive()) {
				try {
					modelCacheJson.init( ((JSONHttpServer)MTG.getPlugin("Json Http Server", MTGServer.class)).getCache().entries() );
					modelCacheJson.fireTableDataChanged();

				}
				catch(Exception ex)
				{
					logger.error("error loading . Maybe Qwartz server is stopped",ex);
				}
			}

		});

		t.start();
	}

	public TechnicalMonitorPanel() {
		setLayout(new BorderLayout(0, 0));
		modelThreads = new ThreadsTableModel();
		modelTasks = new TaskTableModel();
		modelNetwork = new NetworkTableModel();
		queryModel = new QueriesTableModel();
		modelConfig = new MapTableModel<>();
		modelDao = new MapTableModel<>();
		modelCacheJson = new MapTableModel<>();
		modelJsonServerInfo = new JsonInfoTableModel();
		discordModel = new DiscordInfoTableModel();
		gedPanel = new GedBrowserPanel();

		modelScript = new GenericTableModel<JsonObject>()
				{
					private static final long serialVersionUID = 1L;
					@Override
					public Object getValueAt(int row, int column) {
						return items.get(row).get(getColumnName(column));
					}

					@Override
					public String getColumnName(int column) {
						return columns[column];
					}
				};

		var tabs = new JTabbedPane();
		add(tabs, BorderLayout.CENTER);

		modelTasks.bind(TechnicalServiceManager.inst().getTasksInfos());
		modelNetwork.bind(TechnicalServiceManager.inst().getNetworkInfos());
		queryModel.bind(TechnicalServiceManager.inst().getDaoInfos());
		modelJsonServerInfo.bind(TechnicalServiceManager.inst().getJsonInfo());
		discordModel.bind(TechnicalServiceManager.inst().getDiscordInfos());
		modelConfig.init(TechnicalServiceManager.inst().getSystemInfo());
		modelDao.init(MTG.getEnabledPlugin(MTGDao.class).getDBSize());

		var tableTasks = UITools.createNewTable(modelTasks);
		UITools.initTableFilter(tableTasks);

		var tableNetwork = UITools.createNewTable(modelNetwork);
		UITools.initTableFilter(tableNetwork);

		var tableScripts = UITools.createNewTable(modelScript);
		UITools.initTableFilter(tableScripts);

		var tableQueries = UITools.createNewTable(queryModel);
		UITools.initTableFilter(tableQueries);

		var tableDaos = UITools.createNewTable(modelDao);
		UITools.initTableFilter(tableDaos);

		var tableCacheJson = UITools.createNewTable(modelCacheJson);
		UITools.initTableFilter(tableCacheJson);

		var tableJsonInfo= UITools.createNewTable(modelJsonServerInfo);
		UITools.initTableFilter(tableJsonInfo);

		var tableDiscordInfo= UITools.createNewTable(discordModel);
		UITools.initTableFilter(tableDiscordInfo);

		TableCellRenderer durationRenderer = (JTable table, Object value, boolean isSelected,boolean hasFocus, int row, int column)->{

						var lab= new JLabel(DurationFormatUtils.formatDurationHMS((Long)value));
						lab.setOpaque(false);
						return lab;
				};

		TableCellRenderer sizeRenderer = (JTable table, Object value, boolean isSelected,boolean hasFocus, int row, int column)->{
					var lab= new JLabel(UITools.humanReadableSize((Long)value));
					lab.setOpaque(false);
					return lab;
			};

		tableTasks.setDefaultRenderer(Long.class, durationRenderer);
		tableNetwork.setDefaultRenderer(Long.class, durationRenderer);
		tableQueries.setDefaultRenderer(Long.class, durationRenderer);
		tableDaos.setDefaultRenderer(Long.class, sizeRenderer);
		tableJsonInfo.setDefaultRenderer(Long.class, durationRenderer);
		tableDiscordInfo.setDefaultRenderer(Long.class, durationRenderer);

		tabs.addTab("Config",MTGConstants.ICON_SMALL_HELP,new JScrollPane(UITools.createNewTable(modelConfig)));
		tabs.addTab("Threads",MTGConstants.ICON_TAB_ADMIN,new JScrollPane(UITools.createNewTable(modelThreads)));
		tabs.addTab("Tasks",MTGConstants.ICON_TAB_ADMIN,new JScrollPane(tableTasks));
		tabs.addTab("Network",MTGConstants.ICON_TAB_NETWORK,new JScrollPane(tableNetwork));
		tabs.addTab("Qwartz Script",MTGConstants.ICON_SMALL_SCRIPT,new JScrollPane(tableScripts));
		tabs.addTab("Queries",MTGConstants.ICON_TAB_DAO,new JScrollPane(tableQueries));
		tabs.addTab("DB Size",MTGConstants.ICON_TAB_DAO,new JScrollPane(tableDaos));
		tabs.addTab("Discord",ImageTools.resize(new DiscordBotServer().getIcon(),15,15)  ,new JScrollPane(tableDiscordInfo));
		tabs.addTab("JsonServer Cache",MTGConstants.ICON_TAB_CACHE,new JScrollPane(tableCacheJson));
		tabs.addTab("JsonServer Queries",MTGConstants.ICON_TAB_SERVER,new JScrollPane(tableJsonInfo));
		UITools.addTab(tabs, new LoggerViewPanel());
		UITools.addTab(tabs, gedPanel);

		var panel = new JPanel();
		add(panel, BorderLayout.NORTH);

		memoryPanel = new JVMemoryPanel();
		panel.add(memoryPanel);

		t = new Timer(5000, e ->{
			modelThreads.init(TechnicalServiceManager.inst().getThreadsInfos());
			memoryPanel.refresh();
			modelTasks.fireTableDataChanged();
			modelNetwork.fireTableDataChanged();
			modelConfig.fireTableDataChanged();
			queryModel.fireTableDataChanged();
			modelDao.fireTableDataChanged();
			modelJsonServerInfo.fireTableDataChanged();
			discordModel.fireTableDataChanged();

			if(MTG.getPlugin("Qwartz", MTGServer.class).isAlive()) {
				try {
					modelScript.bind( ((QwartzServer)MTG.getPlugin("Qwartz", MTGServer.class)).getJobs()  );
					modelScript.setColumns(modelScript.getItems().get(0).keySet().stream().toArray(String[]::new));
					modelScript.fireTableStructureChanged();
					modelScript.fireTableDataChanged();

				}
				catch(Exception ex)
				{
					logger.error("error loading . Maybe Qwartz server is stopped",ex);
				}
			}

			if(MTG.getPlugin("Json Http Server", MTGServer.class).isAlive()) {
				try {
					modelCacheJson.init( ((JSONHttpServer)MTG.getPlugin("Json Http Server", MTGServer.class)).getCache().entries() );
					modelCacheJson.fireTableDataChanged();

				}
				catch(Exception ex)
				{
					logger.error("error loading . Maybe Qwartz server is stopped",ex);
				}
			}

		});

		t.start();
	}

Replace Generic With Diamond GenericTableModel<JsonObject> with GenericTableModel<> in method public TechnicalMonitorPanel() from class org.magic.gui.components.TechnicalMonitorPanel


	public static JXTable createNewTable(TableModel mod)
	{
		var table = new JXTable();
				if(mod!=null)
					table.setModel(mod);

				table.setDefaultRenderer(Boolean.class, new BooleanCellEditorRenderer());
				table.setDefaultRenderer(Double.class, new DoubleCellEditorRenderer());
				table.setDefaultRenderer(Integer.class, new NumberCellEditorRenderer());
				table.setDefaultRenderer(Long.class, new NumberCellEditorRenderer());
				table.setDefaultRenderer(boolean.class, new BooleanCellEditorRenderer());
				table.setDefaultRenderer(double.class, new DoubleCellEditorRenderer());
				table.setDefaultRenderer(int.class, new NumberCellEditorRenderer());

				table.setDefaultRenderer(Date.class, new DateTableCellEditorRenderer());
				table.setDefaultRenderer(Instant.class, new DateTableCellEditorRenderer());
				table.setDefaultRenderer(MagicEdition.class, new MagicEditionJLabelRenderer());
				table.setDefaultRenderer(MTGPlugin.class, new MTGPluginCellRenderer());
				table.setDefaultRenderer(Player.class, new PlayerRenderer());

				table.setDefaultEditor(Double.class, new DoubleCellEditorRenderer());
				table.setDefaultEditor(Integer.class, new NumberCellEditorRenderer());
				table.setDefaultEditor(Long.class, new NumberCellEditorRenderer());
				table.setDefaultEditor(Boolean.class, new BooleanCellEditorRenderer());
				table.setDefaultEditor(boolean.class, new BooleanCellEditorRenderer());
				table.setDefaultEditor(int.class, new NumberCellEditorRenderer());
				table.setDefaultEditor(double.class, new DoubleCellEditorRenderer());
				table.setDefaultEditor(Date.class, new DateTableCellEditorRenderer());
				table.setDefaultEditor(EnumCondition.class, new ComboBoxEditor<>(EnumCondition.values()));
				table.setDefaultEditor(TransactionStatus.class, new ComboBoxEditor<>(TransactionStatus.values()));
				table.setDefaultEditor(Level.class,  new ComboBoxEditor<>(MTGLogger.getLevels()) );

				try {
					table.setDefaultEditor(MagicCollection.class, new ComboBoxEditor<>(getEnabledPlugin(MTGDao.class).listCollections()));
				} catch (Exception e1) {
					logger.error(e1);
				}

				table.setColumnControlVisible(true);
				table.putClientProperty("terminateEditOnFocusLost", true);
				table.setRowHeight(MTGConstants.TABLE_ROW_HEIGHT);
				table.setPreferredScrollableViewportSize(new java.awt.Dimension(800,600));
				try {
					table.packAll();
				}
				catch(Exception e)
				{
					//do nothing
				}

		return table;
	}

	public static JXTable createNewTable(TableModel mod)
	{
		var table = new JXTable();
				if(mod!=null)
					table.setModel(mod);

				table.setDefaultRenderer(Boolean.class, new BooleanCellEditorRenderer());
				table.setDefaultRenderer(Double.class, new DoubleCellEditorRenderer());
				table.setDefaultRenderer(Integer.class, new NumberCellEditorRenderer());
				table.setDefaultRenderer(Long.class, new NumberCellEditorRenderer());
				table.setDefaultRenderer(boolean.class, new BooleanCellEditorRenderer());
				table.setDefaultRenderer(double.class, new DoubleCellEditorRenderer());
				table.setDefaultRenderer(int.class, new NumberCellEditorRenderer());

				table.setDefaultRenderer(Date.class, new DateTableCellEditorRenderer());
				table.setDefaultRenderer(Instant.class, new DateTableCellEditorRenderer());
				table.setDefaultRenderer(MagicEdition.class, new MagicEditionJLabelRenderer());
				table.setDefaultRenderer(MTGPlugin.class, new MTGPluginCellRenderer());
				table.setDefaultRenderer(Player.class, new PlayerRenderer());

				table.setDefaultEditor(Double.class, new DoubleCellEditorRenderer());
				table.setDefaultEditor(Integer.class, new NumberCellEditorRenderer());
				table.setDefaultEditor(Long.class, new NumberCellEditorRenderer());
				table.setDefaultEditor(Boolean.class, new BooleanCellEditorRenderer());
				table.setDefaultEditor(boolean.class, new BooleanCellEditorRenderer());
				table.setDefaultEditor(int.class, new NumberCellEditorRenderer());
				table.setDefaultEditor(double.class, new DoubleCellEditorRenderer());
				table.setDefaultEditor(Date.class, new DateTableCellEditorRenderer());
				table.setDefaultEditor(EnumCondition.class, new ComboBoxEditor<>(EnumCondition.values()));
				table.setDefaultEditor(TransactionStatus.class, new ComboBoxEditor<>(TransactionStatus.values()));
				table.setDefaultEditor(Level.class,  new ComboBoxEditor<Level>(MTGLogger.getLevels()) );

				try {
					table.setDefaultEditor(MagicCollection.class, new ComboBoxEditor<>(getEnabledPlugin(MTGDao.class).listCollections()));
				} catch (Exception e1) {
					logger.error(e1);
				}

				table.setColumnControlVisible(true);
				table.putClientProperty("terminateEditOnFocusLost", true);
				table.setRowHeight(MTGConstants.TABLE_ROW_HEIGHT);
				table.setPreferredScrollableViewportSize(new java.awt.Dimension(800,600));
				try {
					table.packAll();
				}
				catch(Exception e)
				{
					//do nothing
				}

		return table;
	}

Replace Generic With Diamond ComboBoxEditor<Level> with ComboBoxEditor<> in method public createNewTable(mod TableModel) : JXTable from class org.magic.tools.UITools


	private void init()
	{
		serv = new CardTraderService(getAuthenticator().get("TOKEN"));

		serv.setListener((URLCallInfo callInfo)->{
				var netinfo = new NetworkInfo();

				netinfo.setDuration(callInfo.getDuration());
				netinfo.setEnd(callInfo.getStart());
				netinfo.setStart(callInfo.getStart());
				netinfo.setRequest(callInfo.getRequest());
				netinfo.setReponse(callInfo.getResponse());

				URLTools.getNetworksInfos().add(netinfo);

		});

	}

	private void init()
	{
		serv = new CardTraderService(getAuthenticator().get("TOKEN"));

		serv.setListener(new URLCallListener() {

			@Override
			public void notify(URLCallInfo callInfo) {
				var netinfo = new NetworkInfo();

				netinfo.setDuration(callInfo.getDuration());
				netinfo.setEnd(callInfo.getStart());
				netinfo.setStart(callInfo.getStart());
				netinfo.setRequest(callInfo.getRequest());
				netinfo.setReponse(callInfo.getResponse());

				URLTools.getNetworksInfos().add(netinfo);

			}
		});

	}

Replace Anonymous With Lambda org.magic.api.exports.impl.CardTraderStockExport.init.setListener.new URLCallListener with (callInfo) -> {var netinfo=new NetworkInfo(); in method private init() : void from class org.magic.api.exports.impl.CardTraderStockExport


	public static BufferedImage fromByteArray(byte[] imagebytes) {
        try  (var stream = new ByteArrayInputStream(imagebytes)){
            if (imagebytes != null && (imagebytes.length > 0)) {
                return ImageIO.read(stream);
            }
            return null;
        } catch (IOException e) {
            throw new IllegalArgumentException(e.toString());
        }
    }

	public static BufferedImage fromByteArray(byte[] imagebytes) {
        try {
            if (imagebytes != null && (imagebytes.length > 0)) {
                return ImageIO.read(new ByteArrayInputStream(imagebytes));
            }
            return null;
        } catch (IOException e) {
            throw new IllegalArgumentException(e.toString());
        }
    }

Try With Resources try(var stream=new ByteArrayInputStream(imagebytes)) in method public fromByteArray(imagebytes byte[]) : BufferedImage from class org.magic.tools.ImageTools


	@Override
	public MagicDeck importDeck(String f,String dname) throws IOException {
		MagicDeck deck = new MagicDeck();
		deck.setName(dname);

		try (StringReader sr = new StringReader(f)){
			Document d = XMLTools.createSecureXMLFactory().newDocumentBuilder().parse(new InputSource(sr));
			XPath xpath = XPathFactory.newInstance().newXPath();
			XPathExpression expr = xpath.compile("//section[@name='Main']/card");
			NodeList result = (NodeList) expr.evaluate(d, XPathConstants.NODESET);
			for (int i = 0; i < result.getLength(); i++) {
				Node it = result.item(i);
				String name = it.getTextContent();
				String qte = it.getAttributes().getNamedItem("qty").getNodeValue();
				MagicCard mc = getEnabledPlugin(MTGCardsProvider.class)
						.searchCardByName( name, null, true).get(0);

				deck.getMain().put(mc, Integer.parseInt(qte));
				notify(mc);
			}

			expr = xpath.compile("//section[@name='Sideboard']/card");
			result = (NodeList) expr.evaluate(d, XPathConstants.NODESET);
			for (int i = 0; i < result.getLength(); i++) {
				Node it = result.item(i);
				String name = it.getTextContent();
				String qte = it.getAttributes().getNamedItem("qty").getNodeValue();
				MagicCard mc = getEnabledPlugin(MTGCardsProvider.class)
						.searchCardByName( name, null, true).get(0);

				deck.getSideBoard().put(mc, Integer.parseInt(qte));
				notify(mc);
			}
			return deck;
		} catch (Exception e) {
			throw new IOException(e);
		}
	}

	@Override
	public MagicDeck importDeck(String f,String dname) throws IOException {
		MagicDeck deck = new MagicDeck();
		deck.setName(dname);

		try {
			Document d = XMLTools.createSecureXMLFactory().newDocumentBuilder().parse(new InputSource(new StringReader(f)));
			XPath xpath = XPathFactory.newInstance().newXPath();
			XPathExpression expr = xpath.compile("//section[@name='Main']/card");
			NodeList result = (NodeList) expr.evaluate(d, XPathConstants.NODESET);
			for (int i = 0; i < result.getLength(); i++) {
				Node it = result.item(i);
				String name = it.getTextContent();
				String qte = it.getAttributes().getNamedItem("qty").getNodeValue();
				MagicCard mc = getEnabledPlugin(MTGCardsProvider.class)
						.searchCardByName( name, null, true).get(0);

				deck.getMain().put(mc, Integer.parseInt(qte));
				notify(mc);
			}

			expr = xpath.compile("//section[@name='Sideboard']/card");
			result = (NodeList) expr.evaluate(d, XPathConstants.NODESET);
			for (int i = 0; i < result.getLength(); i++) {
				Node it = result.item(i);
				String name = it.getTextContent();
				String qte = it.getAttributes().getNamedItem("qty").getNodeValue();
				MagicCard mc = getEnabledPlugin(MTGCardsProvider.class)
						.searchCardByName( name, null, true).get(0);

				deck.getSideBoard().put(mc, Integer.parseInt(qte));
				notify(mc);
			}
			return deck;
		} catch (Exception e) {
			throw new IOException(e);
		}
	}

Try With Resources try(StringReader sr=new StringReader(f)) in method public importDeck(f String, dname String) : MagicDeck from class org.magic.api.exports.impl.OCTGNDeckExport


	private void initGUI() {

		setLayout(new BorderLayout(0, 0));
		btnCompare = new JButton("Compare");
		JPanel panneauHaut = new JPanel();
		cboCollections = UITools.createComboboxCollection();
		buzyLabel = AbstractBuzyIndicatorComponent.createProgressComponent();
		model = new DeckStockComparisonModel();
		btnExportMissing = new JExportButton(MODS.EXPORT);
		btnExportMissing.setText("Export Missing");
		UITools.bindJButton(btnExportMissing, KeyEvent.VK_M, "ExportMissing");

		JSplitPane pan = new JSplitPane();
		pan.setDividerLocation(0.5);
		pan.setResizeWeight(0.5);

		pan.setOrientation(JSplitPane.VERTICAL_SPLIT);
		pricesPan = new DeckPricePanel();

		JXTable table = UITools.createNewTable(model);
		UITools.initCardToolTipTable(table, 0,null);

		add(panneauHaut, BorderLayout.NORTH);
		panneauHaut.add(cboCollections);

		chkCollectionCheck = new JCheckBox(MTGControler.getInstance().getLangService().getCapitalize("CHECK_COLLECTION"));
		panneauHaut.add(chkCollectionCheck);

		chkEditionStrict = new JCheckBox(MTGControler.getInstance().getLangService().getCapitalize("EDITION_STRICT"));
		panneauHaut.add(chkEditionStrict);

		panneauHaut.add(btnCompare);
		panneauHaut.add(buzyLabel);

		btnExportMissing.setEnabled(false);
		btnExportMissing.initCardsExport(new Callable<MagicDeck>() {

			@Override
			public MagicDeck call() throws Exception {

				MagicDeck d = new MagicDeck();
				d.setName(currentDeck.getName());
				d.setDescription("Missing cards for deck " + d.getName());
				model.getItems().forEach(l->d.getMain().put(l.getMc(), l.getResult()));

				return d;
			}
		}, buzyLabel);

		panneauHaut.add(btnExportMissing);

		pan.setLeftComponent(new JScrollPane(table));
		pan.setRightComponent(pricesPan);

		add(pan,BorderLayout.CENTER);

		table.setDefaultRenderer(Integer.class, (JTable t, Object value, boolean isSelected, boolean hasFocus,int row, int column)->{
				Integer val = (Integer)value;
				if(column==4)
				{
					JLabel c = new JLabel(value.toString(),SwingConstants.CENTER);
					c.setOpaque(true);
					if(val==0)
					{
						c.setBackground(Color.GREEN);
						c.setForeground(Color.BLACK);
					}

					else
					{
						c.setBackground(Color.RED);
						c.setForeground(Color.WHITE);
					}

					return c;

				}
				return new IntegerCellEditorRenderer().getTableCellRendererComponent(table, value, isSelected, hasFocus,row,column);
		});

		try {
			cboCollections.setSelectedItem(new MagicCollection(MTGControler.getInstance().get("default-library")));
		} catch (Exception e) {
			logger.error("Error retrieving collections",e);
		}

		table.packAll();

	}

	private void initGUI() {

		setLayout(new BorderLayout(0, 0));
		btnCompare = new JButton("Compare");
		JPanel panneauHaut = new JPanel();
		cboCollections = UITools.createComboboxCollection();
		buzyLabel = AbstractBuzyIndicatorComponent.createProgressComponent();
		model = new DeckStockComparisonModel();
		JXTable table = new JXTable();
		btnExportMissing = new JExportButton(MODS.EXPORT);
		btnExportMissing.setText("Export Missing");
		UITools.bindJButton(btnExportMissing, KeyEvent.VK_M, "ExportMissing");

		JSplitPane pan = new JSplitPane();
		pan.setDividerLocation(0.5);
		pan.setResizeWeight(0.5);

		pan.setOrientation(JSplitPane.VERTICAL_SPLIT);
		pricesPan = new DeckPricePanel();

		table.setModel(model);

		UITools.initCardToolTipTable(table, 0,null);

		add(panneauHaut, BorderLayout.NORTH);
		panneauHaut.add(cboCollections);

		chkCollectionCheck = new JCheckBox(MTGControler.getInstance().getLangService().getCapitalize("CHECK_COLLECTION"));
		panneauHaut.add(chkCollectionCheck);

		chkEditionStrict = new JCheckBox(MTGControler.getInstance().getLangService().getCapitalize("EDITION_STRICT"));
		panneauHaut.add(chkEditionStrict);

		panneauHaut.add(btnCompare);
		panneauHaut.add(buzyLabel);

		btnExportMissing.setEnabled(false);
		btnExportMissing.initCardsExport(new Callable<MagicDeck>() {

			@Override
			public MagicDeck call() throws Exception {

				MagicDeck d = new MagicDeck();
				d.setName(currentDeck.getName());
				d.setDescription("Missing cards for deck " + d.getName());
				model.getItems().forEach(l->d.getMain().put(l.getMc(), l.getResult()));

				return d;
			}
		}, buzyLabel);

		panneauHaut.add(btnExportMissing);

		pan.setLeftComponent(new JScrollPane(table));
		pan.setRightComponent(pricesPan);

		add(pan,BorderLayout.CENTER);

		table.setDefaultRenderer(Integer.class, new DefaultTableCellRenderer() {
			private static final long serialVersionUID = 1L;
			@Override
			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,int row, int column) {
				Integer val = (Integer)value;
				if(column==4)
				{
					JLabel c = new JLabel(value.toString());
					c.setOpaque(true);
					if(val==0)
						c.setBackground(Color.GREEN);
					else
						c.setBackground(Color.RED);

					return c;

				}
				return super.getTableCellRendererComponent(table, value, isSelected, hasFocus,row,column);

			}
		});

		try {
			cboCollections.setSelectedItem(new MagicCollection(MTGControler.getInstance().get("default-library")));
		} catch (Exception e) {
			logger.error("Error retrieving collections",e);
		}

		table.packAll();

	}

Replace Anonymous With Lambda org.magic.gui.components.DeckStockComparatorPanel.initGUI.setDefaultRenderer.new DefaultTableCellRenderer with (t, value, isSelected, hasFocus, row, column) -> {Integer val=(Integer)value; in method private initGUI() : void from class org.magic.gui.components.DeckStockComparatorPanel


	@Override
	public void init() {
		propsCache = new Properties();
		try (FileReader fs = new FileReader(fcacheCount))
		{
			propsCache.load(fs);
		}
		catch (FileNotFoundException e) {
			try {
				FileUtils.touch(fcacheCount);
			} catch (IOException e1) {
				logger.error("couldn't create " + fcacheCount, e1);

			}
		} catch (IOException e) {
			logger.error(e);

		}
	}

	@Override
	public void init() {
		propsCache = new Properties();
		try {
			propsCache.load(new FileReader(fcacheCount));
		} catch (FileNotFoundException e) {
			try {
				FileUtils.touch(fcacheCount);
			} catch (IOException e1) {
				logger.error("couldn't create " + fcacheCount, e1);

			}
		} catch (IOException e) {
			logger.error(e);

		}
	}

Try With Resources try(FileReader fs=new FileReader(fcacheCount)) in method public init() : void from class org.magic.api.providers.impl.MagicTheGatheringIOProvider


	private GamePanelGUI() {

		setLayout(new BorderLayout(0, 0));

		panneauDroit = new JPanel();
		stackPanel=new StackPanel(true);

		GameManager.getInstance().getStack().addObserver(stackPanel);

		panelInfo = new JPanel();

		add(panneauDroit, BorderLayout.CENTER);
		panneauDroit.setLayout(new BorderLayout(0, 0));

		panneauDroit.add(panelInfo, BorderLayout.WEST);
		panelInfo.setLayout(new BorderLayout(0, 0));

		JPanel panelActions = new JPanel();
		panelActions.setAlignmentY(Component.TOP_ALIGNMENT);
		panelInfo.add(panelActions, BorderLayout.SOUTH);
		GridBagLayout gblpanelActions = new GridBagLayout();
		gblpanelActions.columnWidths = new int[] { 30, 20, 0, 0 };
		gblpanelActions.rowHeights = new int[] { 0, 23, 0, 0, 0 };
		gblpanelActions.columnWeights = new double[] { 0.0, 0.0, 1.0, Double.MIN_VALUE };
		gblpanelActions.rowWeights = new double[] { 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE };
		panelActions.setLayout(gblpanelActions);

				JButton btnStart = new JButton(MTGConstants.PLAY_ICON);
				btnStart.setToolTipText(MTGControler.getInstance().getLangService().getCapitalize("START"));
				btnStart.addActionListener(ae -> {
					GameManager.getInstance().removePlayers();
					GameManager.getInstance().addPlayer(player);
					GameManager.getInstance().addPlayer(new Player(MTGControler.getInstance().getLangService().getCapitalize("PLAYER") + " 2", 20));
					GameManager.getInstance().initGame();
					manaPoolPanel.init(player.getManaPool());
					player.getManaPool().removeObserver(manaPoolPanel);
					player.getManaPool().addObserver(manaPoolPanel);
					((DefaultListModel<AbstractAction>) listActions.getModel()).removeAllElements();
					player.shuffleLibrary();
					turnsPanel.initTurn();
					new DrawHandActions().actionPerformed(ae);
					clean();
				});

								JButton btnSideboard = new JButton(MTGConstants.ICON_IMPORT);
								btnSideboard.setToolTipText(MTGControler.getInstance().getLangService().getCapitalize("SIDEBOARD"));
								btnSideboard.addActionListener(e -> {
									DeckSideBoardSwitcherDialog gui = new DeckSideBoardSwitcherDialog(player.getDeck());
									gui.setVisible(true);
									player.setDeck(gui.getDeck());
								});

										JButton btnNewGame = new JButton(MTGConstants.ICON_OPEN);
										btnNewGame.setToolTipText(MTGControler.getInstance().getLangService().getCapitalize("CHOOSE_DECK"));
										btnNewGame.addActionListener(ae -> {
											JDeckChooserDialog choose = new JDeckChooserDialog();
											choose.setVisible(true);
											try {
												MagicDeck deck = choose.getSelectedDeck();
												if (deck != null) {

													Player p1 = MTGControler.getInstance().getProfilPlayer();
													p1.setDeck(deck);
													setPlayer(p1);
													GameManager.getInstance().initGame();

												}
											} catch (Exception e) {
												logger.error("Error loading deck", e);
											}
										});
										GridBagConstraints gbcbtnNewGame = new GridBagConstraints();
										gbcbtnNewGame.fill = GridBagConstraints.BOTH;
										gbcbtnNewGame.insets = new Insets(0, 0, 5, 5);
										gbcbtnNewGame.gridx = 0;
										gbcbtnNewGame.gridy = 0;
										panelActions.add(btnNewGame, gbcbtnNewGame);
								GridBagConstraints gbcbtnSideboard = new GridBagConstraints();
								gbcbtnSideboard.fill = GridBagConstraints.HORIZONTAL;
								gbcbtnSideboard.insets = new Insets(0, 0, 5, 5);
								gbcbtnSideboard.gridx = 1;
								gbcbtnSideboard.gridy = 0;
								panelActions.add(btnSideboard, gbcbtnSideboard);

						GridBagConstraints gbcbtnStart = new GridBagConstraints();
						gbcbtnStart.fill = GridBagConstraints.HORIZONTAL;
						gbcbtnStart.insets = new Insets(0, 0, 5, 0);
						gbcbtnStart.gridx = 2;
						gbcbtnStart.gridy = 0;
						panelActions.add(btnStart, gbcbtnStart);

		JPanel panel1 = new JPanel();
		GridBagConstraints gbcpanel1 = new GridBagConstraints();
		gbcpanel1.gridheight = 2;
		gbcpanel1.gridwidth = 3;
		gbcpanel1.insets = new Insets(0, 0, 5, 0);
		gbcpanel1.fill = GridBagConstraints.BOTH;
		gbcpanel1.gridx = 0;
		gbcpanel1.gridy = 1;
		panelActions.add(panel1, gbcpanel1);
		panel1.setLayout(new BorderLayout(0, 0));

		txtChat = new JTextField(MTGControler.getInstance().getLangService().getCapitalize("SAY_SOMETHING"));
		panel1.add(txtChat);
		txtChat.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseClicked(MouseEvent e) {
				txtChat.setText("");
			}
		});

		txtChat.addActionListener(ae -> {
			player.say(txtChat.getText());
			txtChat.setText("");
		});
		txtChat.setColumns(10);

		JPanel panelPoolandDescribes = new JPanel();
		panelInfo.add(panelPoolandDescribes, BorderLayout.CENTER);

		panelPoolandDescribes.setLayout(new BorderLayout(0, 0));

		JPanel panelPoolandHandsLib = new JPanel();
		panelPoolandDescribes.add(panelPoolandHandsLib, BorderLayout.NORTH);
		panelPoolandHandsLib.setLayout(new BorderLayout(0, 0));

		manaPoolPanel = new ManaPoolPanel();
		manaPoolPanel.setMinimumSize(new Dimension(0, 0));
		panelPoolandHandsLib.add(manaPoolPanel, BorderLayout.CENTER);

		JPanel panelHandLib = new JPanel();
		panelPoolandHandsLib.add(panelHandLib, BorderLayout.SOUTH);
		panelHandLib.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

		lblHandCount = new JLabel("0");
		lblHandCount.setFont(new Font(MTGControler.getInstance().getFont().getFontName(), Font.BOLD, 18));
		lblHandCount.setHorizontalTextPosition(SwingConstants.CENTER);
		lblHandCount.setIcon(MTGConstants.ICON_GAME_HAND);
		panelHandLib.add(lblHandCount);

		lblLibraryCount = new JLabel("");
		lblLibraryCount.setHorizontalTextPosition(SwingConstants.CENTER);
		lblLibraryCount.setHorizontalAlignment(SwingConstants.CENTER);
		lblLibraryCount.setFont(new Font(MTGControler.getInstance().getFont().getFontName(), Font.BOLD, 18));
		lblLibraryCount.setIcon(MTGConstants.ICON_GAME_LIBRARY);
		panelHandLib.add(lblLibraryCount);

		JPanel lifePanel = new JPanel();
		panelPoolandHandsLib.add(lifePanel, BorderLayout.WEST);
		lifePanel.setAlignmentY(Component.TOP_ALIGNMENT);
		GridBagLayout gbllifePanel = new GridBagLayout();
		gbllifePanel.columnWidths = new int[] { 60, 0 };
		gbllifePanel.rowHeights = new int[] { 64, 0, 0 };
		gbllifePanel.columnWeights = new double[] { 0.0, Double.MIN_VALUE };
		gbllifePanel.rowWeights = new double[] { 0.0, 0.0, Double.MIN_VALUE };
		lifePanel.setLayout(gbllifePanel);

		lblPlayer = new JLabel("");
		lblPlayer.setVerticalAlignment(SwingConstants.BOTTOM);
		lblPlayer.setIcon(MTGConstants.ICON_GAME_PLANESWALKER);
		GridBagConstraints gbclblPlayer = new GridBagConstraints();
		gbclblPlayer.anchor = GridBagConstraints.WEST;
		gbclblPlayer.insets = new Insets(0, 0, 5, 0);
		gbclblPlayer.gridx = 0;
		gbclblPlayer.gridy = 0;
		lifePanel.add(lblPlayer, gbclblPlayer);

		JPanel panel = new JPanel();
		GridBagConstraints gbcpanel = new GridBagConstraints();
		gbcpanel.anchor = GridBagConstraints.NORTHWEST;
		gbcpanel.gridx = 0;
		gbcpanel.gridy = 1;
		lifePanel.add(panel, gbcpanel);
		panel.setLayout(new GridLayout(2, 2, 0, 0));

		JLabel lblLife = new JLabel("");
		panel.add(lblLife);
		lblLife.setHorizontalAlignment(SwingConstants.CENTER);
		lblLife.setIcon(MTGConstants.ICON_GAME_LIFE);

		spinLife = new JSpinner();
		panel.add(spinLife);
		spinLife.setFont(new Font(MTGControler.getInstance().getFont().getFontName(), Font.BOLD, 17));

		JLabel lblPoison = new JLabel("");
		panel.add(lblPoison);
		lblPoison.setHorizontalAlignment(SwingConstants.CENTER);
		lblPoison.setIcon(MTGConstants.ICON_GAME_POISON);

		spinPoison = new JSpinner();
		panel.add(spinPoison);
		spinPoison.setFont(new Font(MTGControler.getInstance().getFont().getFontName(), Font.BOLD, 15));

		spinPoison.addChangeListener(e -> {
			if (player != null)
				player.setPoisonCounter((int) spinPoison.getValue());

		});
		spinLife.addChangeListener(e -> {
			if (player != null)
				player.setLife((int) spinLife.getValue());
		});

		JTabbedPane tabbedPane = new JTabbedPane(SwingConstants.TOP);
		panelPoolandDescribes.add(tabbedPane, BorderLayout.CENTER);

		listActions = new JList<>();
		listActions.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		listActions.setModel(new DefaultListModel<>());
		JScrollPane scrollActions = new JScrollPane(listActions);
		scrollActions.setPreferredSize(new Dimension((int) MTGControler.getInstance().getCardsGameDimension().getWidth(), 0));
		tabbedPane.addTab(MTGControler.getInstance().getLangService().getCapitalize("EVENTS"), null, scrollActions,null);

		JPanel pane = new JPanel();
		pane.setLayout(new BorderLayout());

		panneauHaut = new LightDescribeCardPanel();
		pane.add(panneauHaut, BorderLayout.CENTER);

		tabbedPane.addTab(MTGControler.getInstance().getLangService().getCapitalize("DESCRIPTION"), MTGConstants.ICON_TAB_DETAILS, pane, null);
		tabbedPane.addTab(MTGControler.getInstance().getLangService().getCapitalize("STACK"), MTGConstants.ICON_TAB_DECK, stackPanel, null);

		JPanel panelPics = new JPanel();
		tabbedPane.addTab(MTGControler.getInstance().getLangService().getCapitalize("PICTURES"), MTGConstants.ICON_TAB_PICTURE, panelPics, null);
		panelPics.setLayout(new BorderLayout(0, 0));

		lblThumbnailPics = new JLabel("");
		lblThumbnailPics.setHorizontalTextPosition(SwingConstants.CENTER);
		lblThumbnailPics.setHorizontalAlignment(SwingConstants.CENTER);
		panelPics.add(lblThumbnailPics);

		JPanel panelLibraryAndGrave = new JPanel();
		panneauDroit.add(panelLibraryAndGrave, BorderLayout.EAST);
		panelLibraryAndGrave.setLayout(new BorderLayout(0, 0));

		JPanel panelDeck = new JPanel();
		panelLibraryAndGrave.add(panelDeck, BorderLayout.NORTH);

		panelLibrary = new LibraryPanel();
		panelLibrary.setPreferredSize(new Dimension(170, 215));
		panelLibrary.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

		panelDeck.setLayout(new BoxLayout(panelDeck, BoxLayout.Y_AXIS));
		panelDeck.add(panelLibrary);

		exilPanel = new ExilPanel();
		exilPanel.setPreferredSize(new Dimension(0, 50));

		panelDeck.add(exilPanel);

		panelLibrary.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent me) {

				if (SwingUtilities.isLeftMouseButton(me)) {
					new DrawActions().actionPerformed(new ActionEvent(me.getSource(), me.getID(), me.paramString()));
				}

			}
		});
		JScrollPane js = new JScrollPane();
		panelGrave = new GraveyardPanel();
		js.setViewportView(panelGrave);
		panelLibraryAndGrave.add(js);

		panelBattleField = new BattleFieldPanel();
		panneauDroit.add(panelBattleField, BorderLayout.CENTER);
		panelBattleField.setLayout(null);

		JPanel panelBottom = new JPanel();
		panneauDroit.add(panelBottom, BorderLayout.SOUTH);

		handPanel = new HandPanel();
		handPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
		handPanel.enableDragging(true);
		handPanel.setThumbnailSize(MTGControler.getInstance().getCardsGameDimension());
		panelBottom.setLayout(new BorderLayout(0, 0));
		handPanel.setRupture(7);

		JScrollPane scrollPane = new JScrollPane(handPanel);
		panelBottom.add(scrollPane);
		scrollPane.setPreferredSize(new Dimension(2, handPanel.getCardHeight()));

		turnsPanel = new TurnsPanel();
		panelBottom.add(turnsPanel, BorderLayout.NORTH);

	}

	private GamePanelGUI() {

		setLayout(new BorderLayout(0, 0));

		panneauDroit = new JPanel();
		stackPanel=new StackPanel(true);

		GameManager.getInstance().getStack().addObserver(stackPanel);

		panelInfo = new JPanel();

		add(panneauDroit, BorderLayout.CENTER);
		panneauDroit.setLayout(new BorderLayout(0, 0));

		panneauDroit.add(panelInfo, BorderLayout.WEST);
		panelInfo.setLayout(new BorderLayout(0, 0));

		JPanel panelActions = new JPanel();
		panelActions.setAlignmentY(Component.TOP_ALIGNMENT);
		panelInfo.add(panelActions, BorderLayout.SOUTH);
		GridBagLayout gblpanelActions = new GridBagLayout();
		gblpanelActions.columnWidths = new int[] { 30, 20, 0, 0 };
		gblpanelActions.rowHeights = new int[] { 0, 23, 0, 0, 0 };
		gblpanelActions.columnWeights = new double[] { 0.0, 0.0, 1.0, Double.MIN_VALUE };
		gblpanelActions.rowWeights = new double[] { 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE };
		panelActions.setLayout(gblpanelActions);

				JButton btnStart = new JButton(MTGConstants.PLAY_ICON);
				btnStart.setToolTipText(MTGControler.getInstance().getLangService().getCapitalize("START"));
				btnStart.addActionListener(ae -> {
					GameManager.getInstance().removePlayers();
					GameManager.getInstance().addPlayer(player);
					GameManager.getInstance().addPlayer(new Player(MTGControler.getInstance().getLangService().getCapitalize("PLAYER") + " 2", 20));
					GameManager.getInstance().initGame();
					manaPoolPanel.init(player.getManaPool());
					player.getManaPool().removeObserver(manaPoolPanel);
					player.getManaPool().addObserver(manaPoolPanel);
					((DefaultListModel<AbstractAction>) listActions.getModel()).removeAllElements();
					player.shuffleLibrary();
					turnsPanel.initTurn();
					new DrawHandActions().actionPerformed(ae);
					clean();
				});

								JButton btnSideboard = new JButton(MTGConstants.ICON_IMPORT);
								btnSideboard.setToolTipText(MTGControler.getInstance().getLangService().getCapitalize("SIDEBOARD"));
								btnSideboard.addActionListener(e -> {
									DeckSideBoardSwitcherDialog gui = new DeckSideBoardSwitcherDialog(player.getDeck());
									gui.setVisible(true);
									player.setDeck(gui.getDeck());
								});

										JButton btnNewGame = new JButton(MTGConstants.ICON_OPEN);
										btnNewGame.setToolTipText(MTGControler.getInstance().getLangService().getCapitalize("CHOOSE_DECK"));
										btnNewGame.addActionListener(ae -> {
											JDeckChooserDialog choose = new JDeckChooserDialog();
											choose.setVisible(true);
											try {
												MagicDeck deck = choose.getSelectedDeck();
												if (deck != null) {

													Player p1 = MTGControler.getInstance().getProfilPlayer();
													p1.setDeck(deck);
													setPlayer(p1);
													GameManager.getInstance().initGame();

												}
											} catch (Exception e) {
												logger.error("Error loading deck", e);
											}
										});
										GridBagConstraints gbcbtnNewGame = new GridBagConstraints();
										gbcbtnNewGame.fill = GridBagConstraints.BOTH;
										gbcbtnNewGame.insets = new Insets(0, 0, 5, 5);
										gbcbtnNewGame.gridx = 0;
										gbcbtnNewGame.gridy = 0;
										panelActions.add(btnNewGame, gbcbtnNewGame);
								GridBagConstraints gbcbtnSideboard = new GridBagConstraints();
								gbcbtnSideboard.fill = GridBagConstraints.HORIZONTAL;
								gbcbtnSideboard.insets = new Insets(0, 0, 5, 5);
								gbcbtnSideboard.gridx = 1;
								gbcbtnSideboard.gridy = 0;
								panelActions.add(btnSideboard, gbcbtnSideboard);

						GridBagConstraints gbcbtnStart = new GridBagConstraints();
						gbcbtnStart.fill = GridBagConstraints.HORIZONTAL;
						gbcbtnStart.insets = new Insets(0, 0, 5, 0);
						gbcbtnStart.gridx = 2;
						gbcbtnStart.gridy = 0;
						panelActions.add(btnStart, gbcbtnStart);

		JPanel panel1 = new JPanel();
		GridBagConstraints gbcpanel1 = new GridBagConstraints();
		gbcpanel1.gridheight = 2;
		gbcpanel1.gridwidth = 3;
		gbcpanel1.insets = new Insets(0, 0, 5, 0);
		gbcpanel1.fill = GridBagConstraints.BOTH;
		gbcpanel1.gridx = 0;
		gbcpanel1.gridy = 1;
		panelActions.add(panel1, gbcpanel1);
		panel1.setLayout(new BorderLayout(0, 0));

		txtChat = new JTextField(MTGControler.getInstance().getLangService().getCapitalize("SAY_SOMETHING"));
		panel1.add(txtChat);
		txtChat.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseClicked(MouseEvent e) {
				txtChat.setText("");
			}
		});

		txtChat.addActionListener(ae -> {
			player.say(txtChat.getText());
			txtChat.setText("");
		});
		txtChat.setColumns(10);

		JPanel panelPoolandDescribes = new JPanel();
		panelInfo.add(panelPoolandDescribes, BorderLayout.CENTER);

		panelPoolandDescribes.setLayout(new BorderLayout(0, 0));

		JPanel panelPoolandHandsLib = new JPanel();
		panelPoolandDescribes.add(panelPoolandHandsLib, BorderLayout.NORTH);
		panelPoolandHandsLib.setLayout(new BorderLayout(0, 0));

		manaPoolPanel = new ManaPoolPanel();
		manaPoolPanel.setMinimumSize(new Dimension(0, 0));
		panelPoolandHandsLib.add(manaPoolPanel, BorderLayout.CENTER);

		JPanel panelHandLib = new JPanel();
		panelPoolandHandsLib.add(panelHandLib, BorderLayout.SOUTH);
		panelHandLib.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

		lblHandCount = new JLabel("0");
		lblHandCount.setFont(new Font(MTGControler.getInstance().getFont().getFontName(), Font.BOLD, 18));
		lblHandCount.setHorizontalTextPosition(SwingConstants.CENTER);
		lblHandCount.setIcon(MTGConstants.ICON_GAME_HAND);
		panelHandLib.add(lblHandCount);

		lblLibraryCount = new JLabel("");
		lblLibraryCount.setHorizontalTextPosition(SwingConstants.CENTER);
		lblLibraryCount.setHorizontalAlignment(SwingConstants.CENTER);
		lblLibraryCount.setFont(new Font(MTGControler.getInstance().getFont().getFontName(), Font.BOLD, 18));
		lblLibraryCount.setIcon(MTGConstants.ICON_GAME_LIBRARY);
		panelHandLib.add(lblLibraryCount);

		JPanel lifePanel = new JPanel();
		panelPoolandHandsLib.add(lifePanel, BorderLayout.WEST);
		lifePanel.setAlignmentY(Component.TOP_ALIGNMENT);
		GridBagLayout gbllifePanel = new GridBagLayout();
		gbllifePanel.columnWidths = new int[] { 60, 0 };
		gbllifePanel.rowHeights = new int[] { 64, 0, 0 };
		gbllifePanel.columnWeights = new double[] { 0.0, Double.MIN_VALUE };
		gbllifePanel.rowWeights = new double[] { 0.0, 0.0, Double.MIN_VALUE };
		lifePanel.setLayout(gbllifePanel);

		lblPlayer = new JLabel("");
		lblPlayer.setVerticalAlignment(SwingConstants.BOTTOM);
		lblPlayer.setIcon(MTGConstants.ICON_GAME_PLANESWALKER);
		GridBagConstraints gbclblPlayer = new GridBagConstraints();
		gbclblPlayer.anchor = GridBagConstraints.WEST;
		gbclblPlayer.insets = new Insets(0, 0, 5, 0);
		gbclblPlayer.gridx = 0;
		gbclblPlayer.gridy = 0;
		lifePanel.add(lblPlayer, gbclblPlayer);

		JPanel panel = new JPanel();
		GridBagConstraints gbcpanel = new GridBagConstraints();
		gbcpanel.anchor = GridBagConstraints.NORTHWEST;
		gbcpanel.gridx = 0;
		gbcpanel.gridy = 1;
		lifePanel.add(panel, gbcpanel);
		panel.setLayout(new GridLayout(2, 2, 0, 0));

		JLabel lblLife = new JLabel("");
		panel.add(lblLife);
		lblLife.setHorizontalAlignment(SwingConstants.CENTER);
		lblLife.setIcon(MTGConstants.ICON_GAME_LIFE);

		spinLife = new JSpinner();
		panel.add(spinLife);
		spinLife.setFont(new Font(MTGControler.getInstance().getFont().getFontName(), Font.BOLD, 17));

		JLabel lblPoison = new JLabel("");
		panel.add(lblPoison);
		lblPoison.setHorizontalAlignment(SwingConstants.CENTER);
		lblPoison.setIcon(MTGConstants.ICON_GAME_POISON);

		spinPoison = new JSpinner();
		panel.add(spinPoison);
		spinPoison.setFont(new Font(MTGControler.getInstance().getFont().getFontName(), Font.BOLD, 15));

		spinPoison.addChangeListener(e -> {
			if (player != null)
				player.setPoisonCounter((int) spinPoison.getValue());

		});
		spinLife.addChangeListener(e -> {
			if (player != null)
				player.setLife((int) spinLife.getValue());
		});

		JTabbedPane tabbedPane = new JTabbedPane(SwingConstants.TOP);
		panelPoolandDescribes.add(tabbedPane, BorderLayout.CENTER);

		listActions = new JList<>();
		listActions.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		listActions.setModel(new DefaultListModel<AbstractAction>());
		JScrollPane scrollActions = new JScrollPane(listActions);
		scrollActions.setPreferredSize(new Dimension((int) MTGControler.getInstance().getCardsGameDimension().getWidth(), 0));
		tabbedPane.addTab(MTGControler.getInstance().getLangService().getCapitalize("EVENTS"), null, scrollActions,null);

		JPanel pane = new JPanel();
		pane.setLayout(new BorderLayout());

		panneauHaut = new LightDescribeCardPanel();
		pane.add(panneauHaut, BorderLayout.CENTER);

		tabbedPane.addTab(MTGControler.getInstance().getLangService().getCapitalize("DESCRIPTION"), MTGConstants.ICON_TAB_DETAILS, pane, null);
		tabbedPane.addTab(MTGControler.getInstance().getLangService().getCapitalize("STACK"), MTGConstants.ICON_TAB_DECK, stackPanel, null);

		JPanel panelPics = new JPanel();
		tabbedPane.addTab(MTGControler.getInstance().getLangService().getCapitalize("PICTURES"), MTGConstants.ICON_TAB_PICTURE, panelPics, null);
		panelPics.setLayout(new BorderLayout(0, 0));

		lblThumbnailPics = new JLabel("");
		lblThumbnailPics.setHorizontalTextPosition(SwingConstants.CENTER);
		lblThumbnailPics.setHorizontalAlignment(SwingConstants.CENTER);
		panelPics.add(lblThumbnailPics);

		JPanel panelLibraryAndGrave = new JPanel();
		panneauDroit.add(panelLibraryAndGrave, BorderLayout.EAST);
		panelLibraryAndGrave.setLayout(new BorderLayout(0, 0));

		JPanel panelDeck = new JPanel();
		panelLibraryAndGrave.add(panelDeck, BorderLayout.NORTH);

		panelLibrary = new LibraryPanel();
		panelLibrary.setPreferredSize(new Dimension(170, 215));
		panelLibrary.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

		panelDeck.setLayout(new BoxLayout(panelDeck, BoxLayout.Y_AXIS));
		panelDeck.add(panelLibrary);

		exilPanel = new ExilPanel();
		exilPanel.setPreferredSize(new Dimension(0, 50));

		panelDeck.add(exilPanel);

		panelLibrary.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent me) {

				if (SwingUtilities.isLeftMouseButton(me)) {
					new DrawActions().actionPerformed(new ActionEvent(me.getSource(), me.getID(), me.paramString()));
				}

			}
		});
		JScrollPane js = new JScrollPane();
		panelGrave = new GraveyardPanel();
		js.setViewportView(panelGrave);
		panelLibraryAndGrave.add(js);

		panelBattleField = new BattleFieldPanel();
		panneauDroit.add(panelBattleField, BorderLayout.CENTER);
		panelBattleField.setLayout(null);

		JPanel panelBottom = new JPanel();
		panneauDroit.add(panelBottom, BorderLayout.SOUTH);

		handPanel = new HandPanel();
		handPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
		handPanel.enableDragging(true);
		handPanel.setThumbnailSize(MTGControler.getInstance().getCardsGameDimension());
		panelBottom.setLayout(new BorderLayout(0, 0));
		handPanel.setRupture(7);

		JScrollPane scrollPane = new JScrollPane(handPanel);
		panelBottom.add(scrollPane);
		scrollPane.setPreferredSize(new Dimension(2, handPanel.getCardHeight()));

		turnsPanel = new TurnsPanel();
		panelBottom.add(turnsPanel, BorderLayout.NORTH);

	}

Replace Generic With Diamond DefaultListModel<AbstractAction> with DefaultListModel<> in method private GamePanelGUI() from class org.magic.game.gui.components.GamePanelGUI