Compare commits

..

1 Commits

Author SHA1 Message Date
Artem Semenovykh
61e87948ab add Singleton in ModelConvertHelper 2024-11-16 13:10:18 +01:00
11802 changed files with 38768 additions and 1140499 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 832 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 856 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2,17 +2,8 @@ package fr.enssat.BoulderDash.helpers;
import fr.enssat.BoulderDash.exceptions.UnknownModelException;
import fr.enssat.BoulderDash.helpers.ModelConvertHelper;
import fr.enssat.BoulderDash.models.ExpandingWallModel;
import fr.enssat.BoulderDash.models.RockfordModel;
import fr.enssat.BoulderDash.models.DisplayableElementModel;
import fr.enssat.BoulderDash.models.EmptyModel;
import fr.enssat.BoulderDash.models.BrickWallModel;
import fr.enssat.BoulderDash.models.BoulderModel;
import fr.enssat.BoulderDash.models.DiamondModel;
import fr.enssat.BoulderDash.models.DirtModel;
import fr.enssat.BoulderDash.models.MagicWallModel;
import fr.enssat.BoulderDash.models.SteelWallModel;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@ -258,8 +249,8 @@ public class LevelLoadHelper {
* @param lineIndex Position in line (vertical axis)
*/
private DisplayableElementModel constructGridElement(String spriteName, int rowIndex, int lineIndex, boolean convertible) throws UnknownModelException {
ModelConvertHelper modelConvert = new ModelConvertHelper();
DisplayableElementModel element = modelConvert.toModel(spriteName, convertible);
ModelConvertHelper modelConvert = ModelConvertHelper.getInstance();
DisplayableElementModel element = modelConvert.toModel(spriteName, convertible);
// Custom actions?
switch (spriteName) {

View File

@ -16,13 +16,17 @@ import fr.enssat.BoulderDash.models.SteelWallModel;
/**
* ModelConvertHelper
*
* Provides model conversion services.
*
* @author Valerian Saliou <valerian@valeriansaliou.name>
* @since 2015-06-22
*/
public class ModelConvertHelper {
/**
* Holds the single instance of the class.
*/
private static ModelConvertHelper instance = null;
/**
* Class constructor
*/
@ -30,6 +34,18 @@ public class ModelConvertHelper {
// Nothing done.
}
/**
* Gets the single instance of the ModelConvertHelper.
* Creates the instance if it doesn't exist.
*
* @return The single instance of the ModelConvertHelper.
*/
public static synchronized ModelConvertHelper getInstance() {
if (instance == null) {
instance = new ModelConvertHelper();
}
return instance;
}
/**
* Gets the model associated to the string
*
@ -37,60 +53,19 @@ public class ModelConvertHelper {
* @return Model associated to given sprite name
*/
public DisplayableElementModel toModel(String spriteName, boolean isConvertible) throws UnknownModelException {
DisplayableElementModel element;
// Instanciates the sprite element matching the given sprite name
switch (spriteName) {
case "black":
case "Black":
element = new EmptyModel();
break;
case "boulder":
case "Boulder":
element = new BoulderModel(isConvertible);
break;
case "brickwall":
case "Brick Wall":
element = new BrickWallModel();
break;
case "diamond":
case "Diamond":
element = new DiamondModel();
break;
case "dirt":
case "Dirt":
element = new DirtModel();
break;
case "magicwall":
case "Magic Wall":
element = new MagicWallModel();
break;
case "rockford":
case "Rockford":
element = new RockfordModel();
break;
case "steelwall":
case "Steel Wall":
element = new SteelWallModel();
break;
case "expandingwall":
case "Expanding Wall":
element = new ExpandingWallModel();
break;
default:
throw new UnknownModelException("Unknown model element > " + spriteName);
}
return element;
// Instantiates the sprite element matching the given sprite name
return switch (spriteName) {
case "black", "Black" -> new EmptyModel();
case "boulder", "Boulder" -> new BoulderModel(isConvertible);
case "brickwall", "Brick Wall" -> new BrickWallModel();
case "diamond", "Diamond" -> new DiamondModel();
case "dirt", "Dirt" -> new DirtModel();
case "magicwall", "Magic Wall" -> new MagicWallModel();
case "rockford", "Rockford" -> new RockfordModel();
case "steelwall", "Steel Wall" -> new SteelWallModel();
case "expandingwall", "Expanding Wall" -> new ExpandingWallModel();
default -> throw new UnknownModelException("Unknown model element > " + spriteName);
};
}
/**

View File

@ -5,16 +5,6 @@ import fr.enssat.BoulderDash.exceptions.UnknownModelException;
import fr.enssat.BoulderDash.helpers.LevelLoadHelper;
import fr.enssat.BoulderDash.helpers.AudioLoadHelper;
import fr.enssat.BoulderDash.helpers.ModelConvertHelper;
import fr.enssat.BoulderDash.models.DisplayableElementModel;
import fr.enssat.BoulderDash.models.RockfordModel;
import fr.enssat.BoulderDash.models.GameInformationModel;
import fr.enssat.BoulderDash.models.SteelWallModel;
import fr.enssat.BoulderDash.models.EmptyModel;
import fr.enssat.BoulderDash.models.DiamondModel;
import fr.enssat.BoulderDash.models.DoorModel;
import fr.enssat.BoulderDash.models.DirtModel;
import fr.enssat.BoulderDash.models.ExpandingWallModel;
import fr.enssat.BoulderDash.models.CursorModel;
import java.awt.image.BufferedImage;
import java.util.Observable;
@ -48,6 +38,11 @@ public class LevelModel extends Observable implements Runnable {
private boolean gamePaused;
// Are we in editor or game mode ?
private String mode;
/**
* Gets the single instance of the ModelConvertHelper.
*/
private ModelConvertHelper modelConverter = ModelConvertHelper.getInstance();
/**
* Sprite animation thread
@ -283,18 +278,15 @@ public class LevelModel extends Observable implements Runnable {
return;
}
// Grab model value
ModelConvertHelper modelConverter = new ModelConvertHelper();
DisplayableElementModel targetModel;
int xPos, yPos;
xPos = this.getCursorXPosition();
yPos = this.getCursorYPosition();
try {
targetModel = modelConverter.toModel(blockValue, false);
DisplayableElementModel targetModel = modelConverter.toModel(blockValue, false);
// Apply new model in place of cursor
// Apply new model in place of cursor
this.groundGrid[xPos + 1][yPos + 1] = targetModel;
// Disable cursor (important)

4
dicegame/.gitignore vendored
View File

@ -1,4 +0,0 @@
.gradle/
.idea/
src/build/
target/

View File

@ -1,4 +0,0 @@
Manifest-Version: 1.0
Class-Path: .
Main-Class: WuerfelspielGUI

View File

@ -1,5 +0,0 @@
package dicegame.logic;
public interface DiceInteraction {
public int changeDiceState(int diceIndex) throws SelectionException;
}

View File

@ -1,276 +0,0 @@
package dicegame.logic;
import java.util.Random;
public class Logic implements DiceInteraction {
public static final int DICE_NUMBER = 6;
public static final int DEFAULT_PLAYER_NUMBER = 2;
public static final int DEFAULT_ROUNDS = 10;
private static final int DIE_UNFIXED = 0;
private static final int DIE_TEMP_FIXED = 1;
private static final int DIE_FIXED = 2;
private boolean gameIsRunning;
private boolean playerCanThrowDice;
private int currentPlayer;
private int roundNumber;
private int roundPoints;
private int maxRounds = DEFAULT_ROUNDS;
private int[] points = new int[2];
private String[] names = new String[2];
private int[] dicePips = new int[6];
private int[] diceFixed = new int[6];
private Random random;
public Logic(Random random) {
this.random = random;
}
public void startGame() {
this.resetGame();
this.gameIsRunning = true;
this.playerCanThrowDice = true;
this.roundNumber = 1;
this.currentPlayer = 0;
}
public String rollDice() {
if (!this.gameIsRunning) {
return "Das Spiel läuft aktuell nicht!";
} else {
if (this.isAllDiceFixed()) {
this.resetDice();
}
for(int i = 0; i < DICE_NUMBER; ++i) {
if (this.diceFixed[i] == DIE_TEMP_FIXED) {
this.diceFixed[i] = DIE_FIXED;
} else if (this.diceFixed[i] == DIE_UNFIXED) {
this.dicePips[i] = this.random.nextInt(6) + 1;
}
}
if (this.isScoringPipsAvailable()) {
this.playerCanThrowDice = true;
} else {
this.playerCanThrowDice = false;
this.roundPoints = 0;
}
return null;
}
}
public boolean isScoringPipsAvailable() {
for(int i = 0; i < DICE_NUMBER; ++i) {
if (this.diceFixed[i] != DIE_FIXED && (this.dicePips[i] == 5 || this.dicePips[i] == 1)) {
return true;
}
}
return false;
}
private boolean isAllDiceFixed() {
for(int i = 0; i < DICE_NUMBER; ++i) {
if (this.diceFixed[i] == DIE_UNFIXED) {
return false;
}
}
return true;
}
public String checkIfGameCanStart() {
if (this.gameIsRunning) {
return "Das Spiel läuft bereits!";
} else {
for(int i = 0; i < DEFAULT_PLAYER_NUMBER; ++i) {
if (this.names[i] == null || this.names[i].trim().length() < 2) {
return "Spieler " + (i + 1) + " hat noch keinen Namen!";
}
}
return null;
}
}
public void resetGame() {
this.roundNumber = 0;
this.roundPoints = 0;
this.resetDice();
this.resetPoints();
}
public void finishRound() {
this.resetDice();
int[] var10000 = this.points;
int var10001 = this.currentPlayer;
var10000[var10001] += this.roundPoints;
this.roundPoints = 0;
this.currentPlayer = ++this.currentPlayer % DEFAULT_PLAYER_NUMBER;
if (this.currentPlayer == 0) {
if (this.roundNumber == this.maxRounds) {
this.gameIsRunning = false;
} else {
++this.roundNumber;
}
}
}
private void resetDice() {
for(int i = 0; i < DICE_NUMBER; ++i) {
this.diceFixed[i] = DIE_UNFIXED;
}
}
private void resetPoints() {
for(int i = 0; i < DEFAULT_PLAYER_NUMBER; ++i) {
this.points[i] = 0;
}
}
public int getRoundNumber() {
return this.roundNumber;
}
public int getRoundPoints() {
return this.roundPoints;
}
public boolean isDieFixed(int dieIndex) {
return this.diceFixed[dieIndex] != DIE_UNFIXED;
}
public boolean isAtLeastOneDieFixedInCurrentThrow() {
for(int i = 0; i < DICE_NUMBER; ++i) {
if (this.diceFixed[i] == DIE_TEMP_FIXED) {
return true;
}
}
return false;
}
private int countTempFixedByPips(int pips) {
int count = 0;
for(int i = 0; i < DICE_NUMBER; ++i) {
if (this.diceFixed[i] == DIE_TEMP_FIXED && this.dicePips[i] == pips) {
++count;
}
}
return count;
}
public int getDiePips(int dieIndex) {
return this.dicePips[dieIndex];
}
public int getMaxRounds() {
return this.maxRounds;
}
public String setMaxRounds(int maxRounds) {
if (this.gameIsRunning) {
return "Rundenzahl kann nicht während eines Spiels verändert werden!";
} else {
this.maxRounds = maxRounds;
return null;
}
}
public int getPoints(int playerIndex) {
return this.points[playerIndex];
}
public String getName(int playerIndex) {
return this.names[playerIndex];
}
public String setName(int playerIndex, String name) {
if (this.gameIsRunning) {
return "Ein Spielername kann nicht während eines Spiels verändert werden!";
} else {
this.names[playerIndex] = name;
return null;
}
}
public boolean isPlayerCanThrowDice() {
return this.playerCanThrowDice;
}
public boolean isGameIsRunning() {
return this.gameIsRunning;
}
public int getCurrentPlayer() {
return this.currentPlayer;
}
@Override
public int changeDiceState(int diceIndex) throws SelectionException {
if (this.diceFixed[diceIndex] == DIE_UNFIXED) {
setDieFixed(diceIndex);
} else {
setDieUnfixed(diceIndex);
}
return roundPoints;
}
private void setDieFixed(int dieIndex) throws SelectionException {
int c;
if (this.dicePips[dieIndex] == 1) {
c = this.countTempFixedByPips(1);
if (c != 2 && c != 5) {
this.roundPoints += 100;
} else {
this.roundPoints -= 200;
this.roundPoints += 1000;
}
this.diceFixed[dieIndex] = DIE_TEMP_FIXED;
} else if (this.dicePips[dieIndex] == 5) {
c = this.countTempFixedByPips(5);
if (c != 2 && c != 5) {
this.roundPoints += 50;
} else {
this.roundPoints -= 100;
this.roundPoints += 500;
}
this.diceFixed[dieIndex] = DIE_TEMP_FIXED;
} else {
throw new SelectionException("Es können nur 1'en und 5'en fixiert werden!");
}
}
private void setDieUnfixed(int dieIndex) throws SelectionException {
int c;
if (this.dicePips[dieIndex] == 1) {
c = this.countTempFixedByPips(1);
if (c != 3 && c != 6) {
this.roundPoints -= 100;
} else {
this.roundPoints -= 1000;
this.roundPoints += 200;
}
this.diceFixed[dieIndex] = DIE_UNFIXED;
} else if (this.dicePips[dieIndex] == 5) {
c = this.countTempFixedByPips(5);
if (c != 3 && c != 6) {
this.roundPoints -= 50;
} else {
this.roundPoints -= 500;
this.roundPoints += 100;
}
this.diceFixed[dieIndex] = DIE_UNFIXED;
}
}
}

View File

@ -1,7 +0,0 @@
package dicegame.logic;
public class SelectionException extends Exception {
SelectionException(String msg) {
super(msg);
}
}

View File

@ -1,608 +0,0 @@
package dicegame.view;
import dicegame.logic.SelectionException;
import dicegame.logic.Logic;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
public final class GUI extends JFrame implements ActionListener {
private final Logic logic;
private static final long serialVersionUID = 1L;
private JPanel jContentPane = null;
private JPanel panelHead = null;
private JPanel panelMain = null;
private JTextField textfieldS1Name = null;
private JLabel labelS1Name = null;
private JLabel labelS2Name = null;
private JTextField textfieldS2Name = null;
private JPanel panelSpieler1 = null;
private JPanel panelSpieler2 = null;
private JLabel labelS1Points = null;
private JLabel labelS1PointsValue = null;
private JLabel labelS2Points = null;
private JLabel labelS2PointsValue = null;
private JPanel panelGoButton = null;
private JButton buttonGo = null;
private JPanel panelRound = null;
private JLabel labelRound = null;
private JLabel labelRoundValue = null;
private JPanel panelDice = null;
private JToggleButton toggleDie1 = null;
private JToggleButton toggleDie2 = null;
private JToggleButton toggleDie3 = null;
private JToggleButton toggleDie4 = null;
private JToggleButton toggleDie5 = null;
private JToggleButton toggleDie6 = null;
private JPanel panelActions = null;
private JPanel panelRoundPoints = null;
private JLabel labelRoundPoints = null;
private JLabel labelRoundPointsValue = null;
private JPanel panelActionsButtons = null;
private JButton buttonRoll = null;
private JButton buttonReady = null;
private JPanel panelDiceActions = null;
private JPanel panelStatus = null;
private JLabel labelStatus = null;
private JPanel getPanelHead() {
if (this.panelHead == null) {
BorderLayout borderLayout3 = new BorderLayout();
borderLayout3.setHgap(3);
borderLayout3.setVgap(3);
this.labelS2Name = new JLabel();
this.labelS2Name.setText("Spieler 2 :");
this.labelS2Name.setFont(new Font("Dialog", 0, 12));
this.labelS2Name.setToolTipText("");
this.labelS1Name = new JLabel();
this.labelS1Name.setText("Spieler 1 :");
this.labelS1Name.setFont(new Font("Dialog", 0, 12));
this.panelHead = new JPanel();
this.panelHead.setLayout(borderLayout3);
this.panelHead.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
this.panelHead.add(this.getPanelSpieler1(), "West");
this.panelHead.add(this.getPanelSpieler2(), "East");
this.panelHead.add(this.getPanelGoButton(), "South");
}
return this.panelHead;
}
private JPanel getPanelMain() {
if (this.panelMain == null) {
BorderLayout borderLayout1 = new BorderLayout();
borderLayout1.setVgap(5);
GridLayout gridLayout3 = new GridLayout();
gridLayout3.setRows(3);
gridLayout3.setColumns(1);
this.panelMain = new JPanel();
this.panelMain.setEnabled(true);
this.panelMain.setBorder(BorderFactory.createEtchedBorder(0));
this.panelMain.setLayout(borderLayout1);
this.panelMain.add(this.getPanelRound(), "North");
this.panelMain.add(this.getPanelDiceActions(), "Center");
}
return this.panelMain;
}
private JTextField getTextfieldS1Name() {
if (this.textfieldS1Name == null) {
this.textfieldS1Name = new JTextField();
this.textfieldS1Name.setColumns(10);
this.textfieldS1Name.setName("");
this.textfieldS1Name.setToolTipText("Name des ersten Spielers, bestehend aus mindestens 2 Zeichen");
this.textfieldS1Name.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
GUI.this.textfieldS2Name.grabFocus();
}
});
this.textfieldS1Name.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent e) {
GUI.this.logic.setName(0, GUI.this.textfieldS1Name.getText());
String s = GUI.this.logic.checkIfGameCanStart();
if (s != null) {
GUI.this.labelStatus.setText(s);
GUI.this.buttonGo.setEnabled(false);
} else {
GUI.this.buttonGo.setEnabled(true);
GUI.this.labelStatus.setText(" ");
}
}
});
}
return this.textfieldS1Name;
}
private JTextField getTextfieldS2Name() {
if (this.textfieldS2Name == null) {
this.textfieldS2Name = new JTextField();
this.textfieldS2Name.setColumns(10);
this.textfieldS2Name.setName("");
this.textfieldS2Name.setToolTipText("Name des zweiten Spielers, bestehend aus mindestens 2 Zeichen");
this.textfieldS2Name.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
GUI.this.buttonGo.grabFocus();
}
});
this.textfieldS2Name.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent e) {
GUI.this.logic.setName(1, GUI.this.textfieldS2Name.getText());
String s = GUI.this.logic.checkIfGameCanStart();
if (s != null) {
GUI.this.labelStatus.setText(s);
GUI.this.buttonGo.setEnabled(false);
} else {
GUI.this.buttonGo.setEnabled(true);
GUI.this.labelStatus.setText(" ");
}
}
});
}
return this.textfieldS2Name;
}
private JPanel getPanelSpieler1() {
if (this.panelSpieler1 == null) {
GridLayout gridLayout21 = new GridLayout();
gridLayout21.setRows(2);
this.labelS1PointsValue = new JLabel();
this.labelS1PointsValue.setText("0");
this.labelS1PointsValue.setFont(new Font("Dialog", 1, 14));
GridLayout gridLayout1 = new GridLayout();
gridLayout1.setRows(2);
gridLayout1.setColumns(2);
this.labelS1Points = new JLabel();
this.labelS1Points.setText("Punkte :");
this.labelS1Points.setFont(new Font("Dialog", 0, 12));
GridLayout gridLayout = new GridLayout();
gridLayout.setRows(2);
gridLayout.setColumns(2);
this.panelSpieler1 = new JPanel();
this.panelSpieler1.setLayout(gridLayout21);
this.panelSpieler1.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
this.panelSpieler1.add(this.labelS1Name, (Object)null);
this.panelSpieler1.add(this.getTextfieldS1Name(), (Object)null);
this.panelSpieler1.add(this.labelS1Points, (Object)null);
this.panelSpieler1.add(this.labelS1PointsValue, (Object)null);
}
return this.panelSpieler1;
}
private JPanel getPanelSpieler2() {
if (this.panelSpieler2 == null) {
this.labelS2PointsValue = new JLabel();
this.labelS2PointsValue.setText("0");
this.labelS2PointsValue.setFont(new Font("Dialog", 1, 14));
this.labelS2Points = new JLabel();
this.labelS2Points.setText("Punkte :");
this.labelS2Points.setFont(new Font("Dialog", 0, 12));
GridLayout gridLayout2 = new GridLayout();
gridLayout2.setRows(2);
gridLayout2.setColumns(2);
this.panelSpieler2 = new JPanel();
this.panelSpieler2.setLayout(gridLayout2);
this.panelSpieler2.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
this.panelSpieler2.add(this.labelS2Name, (Object)null);
this.panelSpieler2.add(this.getTextfieldS2Name(), (Object)null);
this.panelSpieler2.add(this.labelS2Points, (Object)null);
this.panelSpieler2.add(this.labelS2PointsValue, (Object)null);
}
return this.panelSpieler2;
}
private JPanel getPanelGoButton() {
if (this.panelGoButton == null) {
this.panelGoButton = new JPanel();
this.panelGoButton.setLayout(new GridBagLayout());
this.panelGoButton.setEnabled(true);
this.panelGoButton.add(this.getButtonGo(), new GridBagConstraints());
}
return this.panelGoButton;
}
private JButton getButtonGo() {
if (this.buttonGo == null) {
this.buttonGo = new JButton();
this.buttonGo.setName("");
this.buttonGo.setEnabled(false);
this.buttonGo.setText(" Spiel starten ");
this.buttonGo.addActionListener(this);
}
return this.buttonGo;
}
private JPanel getPanelRound() {
if (this.panelRound == null) {
this.labelRoundValue = new JLabel();
this.labelRoundValue.setText("0");
this.labelRoundValue.setFont(new Font("Dialog", 0, 12));
this.labelRound = new JLabel();
this.labelRound.setText("Runde ");
this.labelRound.setFont(new Font("Dialog", 0, 12));
this.panelRound = new JPanel();
this.panelRound.setLayout(new FlowLayout());
this.panelRound.add(this.labelRound, (Object)null);
this.panelRound.add(this.labelRoundValue, (Object)null);
}
return this.panelRound;
}
private JPanel getPanelDice() {
if (this.panelDice == null) {
GridLayout gridLayout5 = new GridLayout();
gridLayout5.setRows(1);
gridLayout5.setHgap(20);
gridLayout5.setVgap(1);
gridLayout5.setColumns(6);
this.panelDice = new JPanel();
this.panelDice.setPreferredSize(new Dimension(346, 26));
this.panelDice.setBorder(BorderFactory.createEmptyBorder(5, 3, 5, 0));
this.panelDice.setLayout(gridLayout5);
this.panelDice.add(this.getToggleDie1(), (Object)null);
this.panelDice.add(this.getToggleDie2(), (Object)null);
this.panelDice.add(this.getToggleDie3(), (Object)null);
this.panelDice.add(this.getToggleDie4(), (Object)null);
this.panelDice.add(this.getToggleDie5(), (Object)null);
this.panelDice.add(this.getToggleDie6(), (Object)null);
}
return this.panelDice;
}
private JToggleButton getToggleDie1() {
if (this.toggleDie1 == null) {
this.toggleDie1 = new JToggleButton();
this.toggleDie1.setText("1");
this.toggleDie1.setEnabled(false);
this.toggleDie1.addActionListener(this);
}
return this.toggleDie1;
}
private JToggleButton getToggleDie2() {
if (this.toggleDie2 == null) {
this.toggleDie2 = new JToggleButton();
this.toggleDie2.setText("2");
this.toggleDie2.setEnabled(false);
this.toggleDie2.addActionListener(this);
}
return this.toggleDie2;
}
private JToggleButton getToggleDie3() {
if (this.toggleDie3 == null) {
this.toggleDie3 = new JToggleButton();
this.toggleDie3.setText("3");
this.toggleDie3.setEnabled(false);
this.toggleDie3.addActionListener(this);
}
return this.toggleDie3;
}
private JToggleButton getToggleDie4() {
if (this.toggleDie4 == null) {
this.toggleDie4 = new JToggleButton();
this.toggleDie4.setText("4");
this.toggleDie4.setEnabled(false);
this.toggleDie4.addActionListener(this);
}
return this.toggleDie4;
}
private JToggleButton getToggleDie5() {
if (this.toggleDie5 == null) {
this.toggleDie5 = new JToggleButton();
this.toggleDie5.setText("5");
this.toggleDie5.setEnabled(false);
this.toggleDie5.addActionListener(this);
}
return this.toggleDie5;
}
private JToggleButton getToggleDie6() {
if (this.toggleDie6 == null) {
this.toggleDie6 = new JToggleButton();
this.toggleDie6.setText("6");
this.toggleDie6.setEnabled(false);
this.toggleDie6.addActionListener(this);
}
return this.toggleDie6;
}
private JPanel getPanelActions() {
if (this.panelActions == null) {
BorderLayout borderLayout2 = new BorderLayout();
borderLayout2.setVgap(0);
borderLayout2.setHgap(0);
this.panelActions = new JPanel();
this.panelActions.setLayout(borderLayout2);
this.panelActions.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
this.panelActions.add(this.getPanelRoundPoints(), "West");
this.panelActions.add(this.getPanelActionsButtons(), "East");
}
return this.panelActions;
}
private JPanel getPanelRoundPoints() {
if (this.panelRoundPoints == null) {
this.labelRoundPointsValue = new JLabel();
this.labelRoundPointsValue.setText("0");
this.labelRoundPoints = new JLabel();
this.labelRoundPoints.setText("Punkte des aktuellen Zuges : ");
this.labelRoundPoints.setFont(new Font("Dialog", 0, 12));
this.panelRoundPoints = new JPanel();
this.panelRoundPoints.setLayout(new GridBagLayout());
this.panelRoundPoints.add(this.labelRoundPoints, new GridBagConstraints());
this.panelRoundPoints.add(this.labelRoundPointsValue, new GridBagConstraints());
}
return this.panelRoundPoints;
}
private JPanel getPanelActionsButtons() {
if (this.panelActionsButtons == null) {
GridLayout gridLayout6 = new GridLayout();
gridLayout6.setRows(2);
gridLayout6.setHgap(0);
gridLayout6.setVgap(6);
gridLayout6.setColumns(1);
this.panelActionsButtons = new JPanel();
this.panelActionsButtons.setLayout(gridLayout6);
this.panelActionsButtons.add(this.getButtonRoll(), (Object)null);
this.panelActionsButtons.add(this.getButtonReady(), (Object)null);
}
return this.panelActionsButtons;
}
private JButton getButtonRoll() {
if (this.buttonRoll == null) {
this.buttonRoll = new JButton();
this.buttonRoll.setText("Würfeln");
this.buttonRoll.setEnabled(false);
this.buttonRoll.addActionListener(this);
}
return this.buttonRoll;
}
private JButton getButtonReady() {
if (this.buttonReady == null) {
this.buttonReady = new JButton();
this.buttonReady.setText("Zug beenden");
this.buttonReady.setEnabled(false);
this.buttonReady.addActionListener(this);
}
return this.buttonReady;
}
private JPanel getPanelDiceActions() {
if (this.panelDiceActions == null) {
BorderLayout borderLayout = new BorderLayout();
borderLayout.setHgap(5);
borderLayout.setVgap(5);
this.panelDiceActions = new JPanel();
this.panelDiceActions.setLayout(borderLayout);
this.panelDiceActions.add(this.getPanelDice(), "Center");
this.panelDiceActions.add(this.getPanelActions(), "South");
}
return this.panelDiceActions;
}
private JPanel getPanelStatus() {
if (this.panelStatus == null) {
this.labelStatus = new JLabel();
this.labelStatus.setText(" ");
this.labelStatus.setToolTipText("");
this.labelStatus.setFont(new Font("Arial", 0, 12));
this.panelStatus = new JPanel();
this.panelStatus.setLayout(new BorderLayout());
this.panelStatus.setBorder(BorderFactory.createBevelBorder(1));
this.panelStatus.add(this.labelStatus, "North");
}
return this.panelStatus;
}
public GUI() {
this.initialize();
this.logic = new Logic(new Random());
this.logic.resetGame();
}
private void initialize() {
this.setSize(478, 311);
this.setResizable(false);
this.setDefaultCloseOperation(3);
this.setName("mainFrame");
this.setContentPane(this.getJContentPane());
this.setTitle("Dings");
}
private JPanel getJContentPane() {
if (this.jContentPane == null) {
BorderLayout borderLayout4 = new BorderLayout();
borderLayout4.setHgap(3);
borderLayout4.setVgap(2);
this.jContentPane = new JPanel();
this.jContentPane.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
this.jContentPane.setLayout(borderLayout4);
this.jContentPane.add(this.getPanelHead(), "North");
this.jContentPane.add(this.getPanelMain(), "Center");
this.jContentPane.add(this.getPanelStatus(), "South");
}
return this.jContentPane;
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source != this.textfieldS1Name && source != this.textfieldS2Name) {
if (source == this.buttonGo) {
this.logic.startGame();
this.labelStatus.setText(" ");
this.buttonGo.setEnabled(false);
this.textfieldS1Name.setEditable(false);
this.textfieldS2Name.setEditable(false);
this.buttonReady.setEnabled(true);
this.labelS2PointsValue.setText(String.valueOf(this.logic.getPoints(1)));
this.labelS1PointsValue.setText(String.valueOf(this.logic.getPoints(0)));
this.syncRoundInfoToGui();
this.logic.rollDice();
this.syncLogicDiceToGui();
this.toggleDie1.setEnabled(true);
this.toggleDie2.setEnabled(true);
this.toggleDie3.setEnabled(true);
this.toggleDie4.setEnabled(true);
this.toggleDie5.setEnabled(true);
this.toggleDie6.setEnabled(true);
} else if (source == this.buttonReady) {
this.logic.finishRound();
this.syncRoundInfoToGui();
if (this.logic.isGameIsRunning()) {
this.logic.rollDice();
this.syncLogicDiceToGui();
}
} else if (source == this.buttonRoll) {
if (!this.logic.isAtLeastOneDieFixedInCurrentThrow()) {
this.labelStatus.setText("Wenigstens ein Würfel muss fixiert sein.");
} else {
String s = this.logic.rollDice();
if (s != null) {
this.labelStatus.setText(s);
} else {
this.syncLogicDiceToGui();
}
}
} else if (source == this.toggleDie1) {
this.toggleDie(this.toggleDie1, 0);
} else if (source == this.toggleDie2) {
this.toggleDie(this.toggleDie2, 1);
} else if (source == this.toggleDie3) {
this.toggleDie(this.toggleDie3, 2);
} else if (source == this.toggleDie4) {
this.toggleDie(this.toggleDie4, 3);
} else if (source == this.toggleDie5) {
this.toggleDie(this.toggleDie5, 4);
} else if (source == this.toggleDie6) {
this.toggleDie(this.toggleDie6, 5);
}
}
}
private void toggleDie(JToggleButton die, int dieIndex) {
String result = null;
this.labelStatus.setText(" ");
try {
int resultingPoints = this.logic.changeDiceState(dieIndex);
this.labelRoundPointsValue.setText(String.valueOf(resultingPoints));
} catch (SelectionException e) {
die.setSelected(!die.isSelected());
this.labelStatus.setText(e.getMessage());
}
}
private void syncRoundInfoToGui() {
if (this.logic.isGameIsRunning()) {
this.labelRoundValue.setText(String.valueOf(this.logic.getRoundNumber()));
this.labelRoundPointsValue.setText(String.valueOf(this.logic.getRoundPoints()));
if (this.logic.getCurrentPlayer() == 0) {
this.labelS1Name.setForeground(Color.GREEN);
this.labelS2Name.setForeground(Color.BLACK);
this.labelS2PointsValue.setText(String.valueOf(this.logic.getPoints(1)));
} else {
this.labelS2Name.setForeground(Color.GREEN);
this.labelS1Name.setForeground(Color.BLACK);
this.labelS1PointsValue.setText(String.valueOf(this.logic.getPoints(0)));
}
} else {
this.labelS2Name.setForeground(Color.BLACK);
this.labelS1Name.setForeground(Color.BLACK);
this.textfieldS1Name.setEditable(true);
this.textfieldS2Name.setEditable(true);
this.labelStatus.setText("Das Spiel ist beendet!");
this.buttonReady.setEnabled(false);
this.buttonRoll.setEnabled(false);
this.buttonGo.setEnabled(true);
this.toggleDie1.setEnabled(false);
this.toggleDie2.setEnabled(false);
this.toggleDie3.setEnabled(false);
this.toggleDie4.setEnabled(false);
this.toggleDie5.setEnabled(false);
this.toggleDie6.setEnabled(false);
}
}
private void syncLogicDiceToGui() {
this.syncLogicDieToGui(this.toggleDie1, 0);
this.syncLogicDieToGui(this.toggleDie2, 1);
this.syncLogicDieToGui(this.toggleDie3, 2);
this.syncLogicDieToGui(this.toggleDie4, 3);
this.syncLogicDieToGui(this.toggleDie5, 4);
this.syncLogicDieToGui(this.toggleDie6, 5);
this.buttonRoll.setEnabled(this.logic.isPlayerCanThrowDice());
this.labelRoundPointsValue.setText(String.valueOf(this.logic.getRoundPoints()));
}
private void syncLogicDieToGui(JToggleButton die, int dieIndex) {
die.setText(String.valueOf(this.logic.getDiePips(dieIndex)));
if (this.logic.isDieFixed(dieIndex)) {
die.setForeground(Color.BLUE);
die.setSelected(true);
} else {
die.setForeground(Color.BLACK);
die.setSelected(false);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
GUI thisClass = new GUI();
thisClass.setDefaultCloseOperation(3);
thisClass.setVisible(true);
}
});
}
}

View File

@ -31,9 +31,9 @@
// Install java.
// See https://github.com/devcontainers/features/tree/main/src/java#options for details.
"ghcr.io/devcontainers/features/java:1": {
"version": "21.0.1-librca",
"version": "23.0.1-tem",
"installGradle": false,
"jdkDistro": "librca"
"jdkDistro": "Temurin"
}
}
}

View File

@ -1,10 +1,5 @@
<!--
Describe the changes you have made here: what, why, ...
Link the issue that will be closed, e.g., "Closes #333".
If your PR closes a koppor issue, link it using its URL, e.g., "Closes https://github.com/koppor/jabref/issues/47".
"Closes" is a keyword GitHub uses to link PRs with issues; do not change it.
Don't reference an issue in the PR title because GitHub does not support auto-linking there.
-->
Describe the changes you have made here: what, why, ...
Link the issue that will be closed, e.g., "Closes #333". If your PR closes a koppor issue, link it using its URL, e.g., "Closes https://github.com/koppor/jabref/issues/47".
### Mandatory checks
@ -13,7 +8,8 @@ Don't reference an issue in the PR title because GitHub does not support auto-li
- [x] done; [ ] not done / not applicable
-->
- [ ] Change in `CHANGELOG.md` described in a way that is understandable for the average user (if applicable)
- [x] I own the copyright of the code submitted and I licence it under the [MIT license](https://github.com/JabRef/jabref/blob/main/LICENSE)
- [ ] Change in `CHANGELOG.md` described in a way that is understandable for the average user (if change is visible to the user)
- [ ] Tests created for changes (if applicable)
- [ ] Manually tested changed features in running JabRef (always required)
- [ ] Screenshots added in PR description (for UI changes)

View File

@ -2,12 +2,8 @@
message: |
Your code currently does not meet [JabRef's code guidelines](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/intellij-13-code-style.html).
We use [Checkstyle](https://checkstyle.sourceforge.io/) to identify issues.
The tool reviewdog already placed comments on GitHub to indicate the places. See the tab "Files" in you PR.
Please carefully follow [the setup guide for the codestyle](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/intellij-13-code-style.html).
Afterwards, please [run checkstyle locally](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/intellij-13-code-style.html#run-checkstyle) and fix the issues.
You can check review dog's comments at the tab "Files changed" of your pull request.
- jobName: OpenRewrite
message: |
Your code currently does not meet JabRef's code guidelines.
@ -34,3 +30,8 @@
message: |
While the PR was in progress, a new version of JabRef has been released.
You have to merge `upstream/main` and move your entry in `CHANGELOG.md` up to the section `## [Unreleased]`.
- jobName: 'Unit tests'
message: |
JUnit tests are failing. In the area "Some checks were not successful", locate "Tests / Unit tests (pull_request)" and click on "Details". This brings you to the test output.
You can then run these tests in IntelliJ to reproduce the failing tests locally. We offer a quick test running howto in the section [Final build system checks](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/intellij-12-build.html#final-build-system-checks) in our setup guide.

View File

@ -1,31 +0,0 @@
name: Add greeting to issues for first time contributors
on:
issues:
types:
- labeled
pull_request_target:
types:
- labeled
jobs:
GreetingFirstTimeCodeContribution:
if: ${{ github.event.label.name == 'FirstTimeCodeContribution' }}
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: GreetingFirstTimeCodeContribution
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ github.event.issue.number || github.event.pull_request.number }}
body: |
Welcome to the vibrant world of open-source development with JabRef!
Newcomers, we're excited to have you on board. Start by exploring our [Contributing](https://github.com/JabRef/jabref/blob/main/CONTRIBUTING.md) guidelines, and don't forget to check out our [workspace setup guidelines](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace) to get started smoothly.
In case you encounter failing tests during development, please check our [developer FAQs](https://devdocs.jabref.org/code-howtos/faq.html)!
Having any questions or issues? Feel free to ask here on GitHub. Need help setting up your local workspace? Join the conversation on [JabRef's Gitter chat](https://gitter.im/JabRef/jabref). And don't hesitate to open a (draft) pull request early on to show the direction it is heading towards. This way, you will receive valuable feedback.
Happy coding! 🚀

View File

@ -1,44 +0,0 @@
name: Add to Project on Label
on:
issues:
types: [labeled]
permissions:
issues: write
jobs:
add-to-project:
runs-on: ubuntu-latest
steps:
- name: "good first issue"
if: "${{ github.event.label.name == 'good first issue' }}"
env:
GH_TOKEN: ${{ secrets.GH_TOKEN_PROJECT_ITEM_ADD }}
run: |
ISSUE_URL=$(jq --raw-output .issue.html_url "$GITHUB_EVENT_PATH")
gh project item-add 5 --owner JabRef --url $ISSUE_URL
- name: needs-refinement
if: github.event.label.name == 'needs-refinement'
env:
GH_TOKEN: ${{ secrets.GH_TOKEN_PROJECT_ITEM_ADD }}
run: |
ISSUE_URL=$(jq --raw-output .issue.html_url "$GITHUB_EVENT_PATH")
gh project item-add 15 --owner JabRef --url $ISSUE_URL
- name: "status: freeze"
if: "${{ github.event.label.name == 'status: freeze' }}"
env:
GH_TOKEN: ${{ secrets.GH_TOKEN_PROJECT_ITEM_ADD }}
run: |
ISSUE_URL=$(jq --raw-output .issue.html_url "$GITHUB_EVENT_PATH")
gh project item-add 9 --owner JabRef --url $ISSUE_URL
- name: ui
if: "${{ github.event.label.name == 'ui' }}"
env:
GH_DEBUG: api
GH_TOKEN: ${{ secrets.GH_TOKEN_PROJECT_ITEM_ADD }}
run: |
ISSUE_URL=$(jq --raw-output .issue.html_url "$GITHUB_EVENT_PATH")
echo $ISSUE_URL
gh project item-add 8 --owner JabRef --url $ISSUE_URL

View File

@ -0,0 +1,57 @@
name: Assign Issue
on:
schedule:
- cron: 4 12 * * *
issue_comment:
types: [created]
workflow_dispatch:
jobs:
assign:
if: github.repository_owner == 'JabRef'
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Assign the user or unassign stale assignments
id: assign
uses: takanome-dev/assign-issue-action@beta
with:
github_token: '${{ secrets.GITHUB_TOKEN }}'
days_until_unassign: 30
maintainers: koppor, Siedlerchr, ThiloteE, calixtus, HoussemNasri
assigned_comment: |
👋 Hey @{{ handle }}, thank you for your interest in this issue! 🎉
We're excited to have you on board. Start by exploring our [Contributing](https://github.com/JabRef/jabref/blob/main/CONTRIBUTING.md) guidelines, and don't forget to check out our [workspace setup guidelines](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace) to get started smoothly.
In case you encounter failing tests during development, please check our [developer FAQs](https://devdocs.jabref.org/code-howtos/faq.html)!
Having any questions or issues? Feel free to ask here on GitHub. Need help setting up your local workspace? Join the conversation on [JabRef's Gitter chat](https://gitter.im/JabRef/jabref). And don't hesitate to open a (draft) pull request early on to show the direction it is heading towards. This way, you will receive valuable feedback.
Happy coding! 🚀
⏳ Please note, you will be automatically unassigned if the issue isn't closed within **{{ total_days }} days** (by **{{ unassigned_date }}**). A maintainer can also add the "**{{ pin_label }}**"" label to prevent automatic unassignment.
- name: Move Issue to "Assigned" Column in "Candidates for University Projects"
if: steps.assign.outputs.assigned == 'yes'
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/3"
target-labels: "📍 Assigned"
target-column: "Assigned"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true
- name: Move Issue to "Assigned" Column in "Good First Issues"
if: steps.assign.outputs.assigned == 'yes'
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/5"
target-labels: "📍 Assigned"
target-column: "Assigned"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true

View File

@ -10,13 +10,13 @@ jobs:
runs-on: ubuntu-latest
# Run only if PR is inside JabRef's main repository and created by dependabot or by an update workflow
if: >
(github.repository == 'JabRef/jabref') &&
(github.repository == 'JabRef/jabref') &&
(github.event.pull_request.head.repo.full_name == 'JabRef/jabref') &&
(
(github.actor == 'dependabot[bot]') ||
(
startsWith(github.event.pull_request.title, '[Bot] ') ||
startsWith(github.event.pull_request.title, 'Bump ') ||
startsWith(github.event.pull_request.title, '[Bot] ') ||
startsWith(github.event.pull_request.title, 'Bump ') ||
startsWith(github.event.pull_request.title, 'New Crowdin updates') ||
startsWith(github.event.pull_request.title, 'Update Gradle Wrapper from')
)
@ -26,9 +26,9 @@ jobs:
run: gh pr review --approve "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GITHUB_TOKEN: ${{secrets.GH_TOKEN_JABREF_MACHINE_PR_APPROVE}}
GH_TOKEN: ${{secrets.GH_TOKEN_JABREF_MACHINE_PR_APPROVE}}
- name: Merge PR
run: gh pr merge --auto --squash "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GITHUB_TOKEN: ${{secrets.GH_TOKEN_UPDATE_GRADLE_WRAPPER}}
GH_TOKEN: ${{secrets.GH_TOKEN_UPDATE_GRADLE_WRAPPER}}

View File

@ -18,6 +18,7 @@ concurrency:
jobs:
lychee:
if: github.repository_owner == 'JabRef'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -31,7 +32,7 @@ jobs:
restore-keys: cache-lychee-
- name: Link Checker
id: lychee
uses: lycheeverse/lychee-action@v1.10.0
uses: lycheeverse/lychee-action@v2.1.0
with:
fail: true
args: --accept '200,201,202,203,204,403,429,500' --max-concurrency 1 --cache --no-progress --exclude-all-private './**/*.md'

View File

@ -6,6 +6,7 @@ on:
jobs:
cleanup:
if: github.repository_owner == 'JabRef'
runs-on: ubuntu-latest
steps:
- name: Cancel deployment run
@ -28,7 +29,7 @@ jobs:
BUILDJABREFPRIVATEKEY: ${{ secrets.buildJabRefPrivateKey }}
- name: Delete folder on builds.jabref.org
if: steps.checksecrets.outputs.secretspresent == 'YES'
uses: appleboy/ssh-action@v1.0.3
uses: appleboy/ssh-action@v1.1.0
with:
script: rm -rf /var/www/builds.jabref.org/www/pull/${{ github.event.pull_request.number }} || true
host: build-upload.jabref.org
@ -37,8 +38,8 @@ jobs:
key: ${{ secrets.buildJabRefPrivateKey }}
- name: Update PR comment
if: steps.checksecrets.outputs.secretspresent == 'YES'
uses: thollander/actions-comment-pull-request@v2
uses: thollander/actions-comment-pull-request@v3
with:
comment_tag: download-link
comment-tag: download-link
message: The build for this PR is no longer available. Please visit <https://builds.jabref.org/main/> for the latest build.
mode: upsert

View File

@ -34,6 +34,7 @@ concurrency:
jobs:
build:
if: github.repository_owner == 'JabRef'
strategy:
fail-fast: false
matrix:
@ -77,7 +78,7 @@ jobs:
- name: Setup JDK
uses: actions/setup-java@v4
with:
java-version: 21.0.2
java-version: 23.0.1
distribution: 'temurin'
- name: Clean up keychain
run: |
@ -205,7 +206,7 @@ jobs:
if: ${{ (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) && (steps.checksecrets.outputs.secretspresent == 'YES') && ((matrix.os == 'ubuntu-latest') || ((matrix.os == 'macos-14') && !((startsWith(github.ref, 'refs/tags/') || inputs.notarization == true)))) }}
shell: bash
run: |
rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }} && rsync" -e 'ssh -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }}/
rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }} && rsync" -e 'ssh -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }}/ || true
- name: Upload to GitHub workflow artifacts store (macOS)
if: (matrix.os == 'macos-14') && (steps.checksecrets.outputs.secretspresent == 'YES') && (startsWith(github.ref, 'refs/tags/') || inputs.notarization == true)
uses: actions/upload-artifact@v4

View File

@ -32,12 +32,13 @@ concurrency:
jobs:
build:
if: github.repository_owner == 'JabRef'
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest, buildjet-8vcpu-ubuntu-2204-arm]
jdk: [22]
javafx: [23]
jdk: [23]
javafx: [24]
include:
- os: ubuntu-latest
displayName: linux
@ -266,7 +267,7 @@ jobs:
shell: cmd
# for rsync installed by chocolatey, we need the ssh.exe delivered with that installation
run: |
rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/jdk-ea && rsync" -e 'C:\ProgramData\chocolatey\lib\rsync\tools\bin\ssh.exe -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/jdk-ea/
rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/jdk-ea && rsync" -e 'C:\ProgramData\chocolatey\lib\rsync\tools\bin\ssh.exe -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/jdk-ea/ || true
- name: Upload to builds.jabref.org (linux, macOS)
if: (matrix.os != 'windows-latest') && (steps.checksecrets.outputs.secretspresent == 'YES') && (github.ref == 'refs/heads/main')
shell: bash

View File

@ -90,7 +90,7 @@ jobs:
- name: Setup JDK
uses: actions/setup-java@v4
with:
java-version: 21.0.2
java-version: 23.0.1
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
@ -242,7 +242,7 @@ jobs:
shell: cmd
# for rsync installed by chocolatey, we need the ssh.exe delivered with that installation
run: |
rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }} && rsync" -e 'C:\ProgramData\chocolatey\lib\rsync\tools\bin\ssh.exe -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }}/
rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }} && rsync" -e 'C:\ProgramData\chocolatey\lib\rsync\tools\bin\ssh.exe -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }}/ || true
- name: Upload to builds.jabref.org (linux, macOS)
# macOS: Negated condition of "Upload to GitHub workflow artifacts store (macOS)"
# Reason: We either upload the non-notarized files - or notarize the files later (and upload these later)
@ -250,7 +250,7 @@ jobs:
if: ${{ (!startsWith(github.ref, 'refs/heads/gh-readonly-queue')) && (steps.checksecrets.outputs.secretspresent == 'YES') && ((matrix.os == 'ubuntu-latest') || ((matrix.os == 'macos-13') && !((startsWith(github.ref, 'refs/tags/') || inputs.notarization == true)))) }}
shell: bash
run: |
rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }} && rsync" -e 'ssh -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }}/
rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }} && rsync" -e 'ssh -p 9922 -i sshkey -o StrictHostKeyChecking=no' build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }}/ || true
- name: Upload to GitHub workflow artifacts store (macOS)
if: (matrix.os == 'macos-13') && (steps.checksecrets.outputs.secretspresent == 'YES') && (startsWith(github.ref, 'refs/tags/') || inputs.notarization == true)
uses: actions/upload-artifact@v4
@ -287,11 +287,11 @@ jobs:
BUILDJABREFPRIVATEKEY: ${{ secrets.buildJabRefPrivateKey }}
- name: Comment PR
if: (steps.checksecrets.outputs.secretspresent == 'YES')
uses: thollander/actions-comment-pull-request@v2
uses: thollander/actions-comment-pull-request@v3
with:
message: |
The build of this PR is available at <https://builds.jabref.org/pull/${{ github.event.pull_request.number }}/merge>.
comment_tag: download-link
comment-tag: download-link
mode: recreate
notarize: # outsourced in a separate job to be able to rerun if this fails for timeouts
name: macOS notarization

View File

@ -15,6 +15,7 @@ concurrency:
jobs:
action:
if: github.repository_owner == 'JabRef'
runs-on: ubuntu-latest
steps:
- name: 'Checkout'

View File

@ -0,0 +1,124 @@
name: On labeled issue
on:
issues:
types:
- labeled
jobs:
Assigned:
# Triggered when manually assigned the label "📍 Assigned" to trigger the automatic unassignment after 30 days
name: "📍 Assigned"
if: ${{ github.event.label.name == '📍 Assigned' && github.repository_owner == 'JabRef' }}
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Move Issue to "Free to take" Column in "Candidates for University Projects"
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/3"
target-labels: "📍 Assigned"
target-column: "Free to take"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true
- name: Move Issue to "Free to take" Column in "Good First Issues"
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/5"
target-labels: "📍 Assigned"
target-column: "Free to take"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true
FirstTimeCodeContribution:
if: ${{ github.event.label.name == 'FirstTimeCodeContribution' && github.repository_owner == 'JabRef' }}
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: GreetingFirstTimeCodeContribution
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ github.event.issue.number || github.event.pull_request.number }}
body: |
Welcome to the vibrant world of open-source development with JabRef!
Newcomers, we're excited to have you on board. Start by exploring our [Contributing](https://github.com/JabRef/jabref/blob/main/CONTRIBUTING.md) guidelines, and don't forget to check out our [workspace setup guidelines](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace) to get started smoothly.
In case you encounter failing tests during development, please check our [developer FAQs](https://devdocs.jabref.org/code-howtos/faq.html)!
Having any questions or issues? Feel free to ask here on GitHub. Need help setting up your local workspace? Join the conversation on [JabRef's Gitter chat](https://gitter.im/JabRef/jabref). And don't hesitate to open a (draft) pull request early on to show the direction it is heading towards. This way, you will receive valuable feedback.
⚠ Note that this issue will become unassigned if it isn't closed within **30 days**.
🔧 A maintainer can also add the **`Pinned`** label to prevent it from being unassigned automatically.
Happy coding! 🚀
- name: Move Issue to "Assigned" Column in "Candidates for University Projects"
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/3"
target-labels: "FirstTimeCodeContribution"
target-column: "Assigned"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true
- name: Move Issue to "Assigned" Column in "Good First Issues"
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/5"
target-labels: "FirstTimeCodeContribution"
target-column: "Assigned"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true
good-first-issue:
name: "good first issue"
if: "${{ github.event.label.name == 'good first issue' && github.repository_owner == 'JabRef' }}"
runs-on: ubuntu-latest
steps:
- name: "good first issue"
env:
GH_TOKEN: ${{ secrets.GH_TOKEN_PROJECT_ITEM_ADD }}
run: |
ISSUE_URL=$(jq --raw-output .issue.html_url "$GITHUB_EVENT_PATH")
gh project item-add 5 --owner JabRef --url $ISSUE_URL
needs-refinement:
if: github.event.label.name == 'needs-refinement' && github.repository_owner == 'JabRef'
runs-on: ubuntu-latest
steps:
- name: needs-refinement
env:
GH_TOKEN: ${{ secrets.GH_TOKEN_PROJECT_ITEM_ADD }}
run: |
ISSUE_URL=$(jq --raw-output .issue.html_url "$GITHUB_EVENT_PATH")
gh project item-add 15 --owner JabRef --url $ISSUE_URL
status-freeze:
name: "status: freeze"
if: "${{ github.event.label.name == 'status: freeze' && github.repository_owner == 'JabRef' }}"
runs-on: ubuntu-latest
steps:
- name: "status: freeze"
env:
GH_TOKEN: ${{ secrets.GH_TOKEN_PROJECT_ITEM_ADD }}
run: |
ISSUE_URL=$(jq --raw-output .issue.html_url "$GITHUB_EVENT_PATH")
gh project item-add 9 --owner JabRef --url $ISSUE_URL
ui:
if: "${{ github.event.label.name == 'ui' && github.repository_owner == 'JabRef' }}"
runs-on: ubuntu-latest
steps:
- name: ui
env:
GH_DEBUG: api
GH_TOKEN: ${{ secrets.GH_TOKEN_PROJECT_ITEM_ADD }}
run: |
ISSUE_URL=$(jq --raw-output .issue.html_url "$GITHUB_EVENT_PATH")
echo $ISSUE_URL
gh project item-add 8 --owner JabRef --url $ISSUE_URL

View File

@ -0,0 +1,23 @@
name: On labeled PR
on:
pull_request:
types:
- labeled
jobs:
automerge:
name: Auto Merge
if: "${{ github.event.label.name == 'automerge' && github.repository_owner == 'JabRef' }}"
runs-on: ubuntu-latest
steps:
- name: Approve PR
run: gh pr review --approve "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GITHUB_TOKEN: ${{secrets.GH_TOKEN_JABREF_MACHINE_PR_APPROVE}}
- name: Merge PR
run: gh pr merge --auto --squash "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GITHUB_TOKEN: ${{secrets.GH_TOKEN_UPDATE_GRADLE_WRAPPER}}

View File

@ -0,0 +1,34 @@
name: On unlabeled issue
on:
issues:
types:
- unlabeled
jobs:
FirstTimeCodeContribution_or_Assigned:
if: ${{ ((github.event.label.name == 'FirstTimeCodeContribution') || (github.event.label.name == '📍 Assigned')) && github.repository_owner == 'JabRef' }}
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Move Issue to "Free to take" Column in "Candidates for University Projects"
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/3"
target-labels: "📍 Assigned"
target-column: "Assigned"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true
- name: Move Issue to "Free to take" Column in "Good First Issues"
uses: m7kvqbe1/github-action-move-issues@feat/skip-if-not-in-project-flag
with:
github-token: ${{ secrets.GH_TOKEN_ACTION_MOVE_ISSUE }}
project-url: "https://github.com/orgs/JabRef/projects/5"
target-labels: "📍 Assigned"
target-column: "Assigned"
ignored-columns: ""
default-column: "Free to take"
skip-if-not-in-project: true

Some files were not shown because too many files have changed in this diff Show More